Advertisement
Guest User

Untitled

a guest
Jan 30th, 2015
179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.31 KB | None | 0 0
  1. #include<iostream>
  2. #include<cstring>
  3. using namespace std;
  4. /*
  5. IMPORTANT:
  6. Node are from 0 to n - 1
  7. It gives the maximum weight matching in a graph
  8. */
  9. #define N 205 //max number of vertices in one part
  10. #define INF 100000000 //just infinity
  11. int cost[N][N]; //cost matrix
  12. int n, max_match; //n workers and n jobs
  13. int lx[N], ly[N]; //labels of X and Y parts
  14. int xy[N]; //xy[x] - vertex that is matched with x,
  15. int yx[N]; //yx[y] - vertex that is matched with y
  16. bool S[N], T[N]; //sets S and T in algorithm
  17. int slack[N]; //as in the algorithm description
  18. int slackx[N]; //slackx[y] such a vertex, that
  19. // l(slackx[y]) + l(y) - w(slackx[y],y) = slack[y]
  20. int prev[N]; //array for memorizing alternating paths
  21. void init_labels()
  22. {
  23. memset(lx, 0, sizeof(lx));
  24. memset(ly, 0, sizeof(ly));
  25. for (int x = 0; x < n; x++)
  26. for (int y = 0; y < n; y++)
  27. lx[x] = max(lx[x], cost[x][y]);
  28. }
  29. void update_labels()
  30. {
  31. int x, y, delta = INF; //init delta as infinity
  32. for (y = 0; y < n; y++) //calculate delta using slack
  33. if (!T[y])
  34. delta = min(delta, slack[y]);
  35. for (x = 0; x < n; x++) //update X labels
  36. if (S[x]) lx[x] -= delta;
  37. for (y = 0; y < n; y++) //update Y labels
  38. if (T[y]) ly[y] += delta;
  39. for (y = 0; y < n; y++) //update slack array
  40. if (!T[y])
  41. slack[y] -= delta;
  42. }
  43. void add_to_tree(int x, int prevx)
  44. //x - current vertex,prevx - vertex from X before x in the alternating path,
  45. //so we add edges (prevx, xy[x]), (xy[x], x)
  46. {
  47. S[x] = true; //add x to S
  48. prev[x] = prevx; //we need this when augmenting
  49. for (int y = 0; y < n; y++) //update slacks, because we add new vertex to S
  50. if (lx[x] + ly[y] - cost[x][y] < slack[y])
  51. {
  52. slack[y] = lx[x] + ly[y] - cost[x][y];
  53. slackx[y] = x;
  54. }
  55. }
  56. //second part of augment() function
  57. void augment() //main function of the algorithm
  58. {
  59. if (max_match == n) return; //check wether matching is already perfect
  60. int x, y, root; //just counters and root vertex
  61. int q[N], wr = 0, rd = 0; //q - queue for bfs, wr,rd - write and read
  62. //pos in queue
  63. memset(S, false, sizeof(S)); //init set S
  64. memset(T, false, sizeof(T)); //init set T
  65. memset(prev, -1, sizeof(prev)); //init set prev - for the alternating tree
  66. for (x = 0; x < n; x++) //finding root of the tree
  67. if (xy[x] == -1)
  68. {
  69. q[wr++] = root = x;
  70. prev[x] = -2;
  71. S[x] = true;
  72. break;
  73. }
  74.  
  75. for (y = 0; y < n; y++) //initializing slack array
  76. {
  77. slack[y] = lx[root] + ly[y] - cost[root][y];
  78. slackx[y] = root;
  79. }
  80. while (true) //main cycle
  81. {
  82. while (rd < wr) //building tree with bfs cycle
  83. {
  84. x = q[rd++]; //current vertex from X part
  85. for (y = 0; y < n; y++) //iterate through all edges in equality graph
  86. if (cost[x][y] == lx[x] + ly[y] && !T[y])
  87. {
  88. if (yx[y] == -1) break; //an exposed vertex in Y found, so
  89. //augmenting path exists!
  90. T[y] = true; //else just add y to T,
  91. q[wr++] = yx[y]; //add vertex yx[y], which is matched
  92. //with y, to the queue
  93. add_to_tree(yx[y], x); //add edges (x,y) and (y,yx[y]) to the tree
  94. }
  95. if (y < n) break; //augmenting path found!
  96. }
  97. if (y < n) break; //augmenting path found!
  98.  
  99. update_labels(); //augmenting path not found, so improve labeling
  100. wr = rd = 0;
  101. for (y = 0; y < n; y++)
  102. //in this cycle we add edges that were added to the equality graph as a
  103. //result of improving the labeling, we add edge (slackx[y], y) to the tree if
  104. //and only if !T[y] && slack[y] == 0, also with this edge we add another one
  105. //(y, yx[y]) or augment the matching, if y was exposed
  106. if (!T[y] && slack[y] == 0)
  107. {
  108. if (yx[y] == -1) //exposed vertex in Y found - augmenting path exists!
  109. {
  110. x = slackx[y];
  111. break;
  112. }
  113. else
  114. {
  115. T[y] = true; //else just add y to T,
  116. if (!S[yx[y]])
  117. {
  118. q[wr++] = yx[y]; //add vertex yx[y], which is matched with
  119. //y, to the queue
  120. add_to_tree(yx[y], slackx[y]); //and add edges (x,y) and (y,
  121. //yx[y]) to the tree
  122. }
  123. }
  124. }
  125. if (y < n) break; //augmenting path found!
  126. }
  127. if (y < n) //we found augmenting path!
  128. {
  129. max_match++; //increment matching
  130. //in this cycle we inverse edges along augmenting path
  131. for (int cx = x, cy = y, ty; cx != -2; cx = prev[cx], cy = ty)
  132. {
  133. ty = xy[cx];
  134. yx[cy] = cx;
  135. xy[cx] = cy;
  136. }
  137. augment(); //recall function, go to step 1 of the algorithm
  138. }
  139. }//end of augment() function
  140. int hungarian()
  141. {
  142. int ret = 0; //weight of the optimal matching
  143. max_match = 0; //number of vertices in current matching
  144. memset(xy, -1, sizeof(xy));
  145. memset(yx, -1, sizeof(yx));
  146. init_labels(); //step 0
  147. augment(); //steps 1-3
  148. for (int x = 0; x < n; x++) //forming answer there
  149. ret += cost[x][xy[x]];
  150. return ret;
  151. }
  152. int main()
  153. {
  154. int t;
  155. cin>>t;
  156. while(t--)
  157. {
  158. cin>>n;
  159. int i,j;
  160. memset(cost,0,sizeof(cost));
  161. int m;
  162. cin>>m;
  163. while(m--)
  164. {
  165. int a,b,c;
  166. cin>>a>>b>>c;
  167. a--;b--;
  168. cost[a][b] = 5*int(1e6) - c;
  169. }
  170. int t1 = hungarian();
  171. int n1 = n * int(1e6)*5 - t1;
  172. if(t1 < int(1e6) * 4 * n)cout<<"Impossible\n";
  173. else cout<<n1<<endl;
  174. }
  175. int i;cin>>i;
  176. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement