MinCostMaxFlow.cc 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // Implementation of min cost max flow algorithm using adjacency
  2. // matrix (Edmonds and Karp 1972). This implementation keeps track of
  3. // forward and reverse edges separately (so you can set cap[i][j] !=
  4. // cap[j][i]). For a regular max flow, set all edge costs to 0.
  5. // Running time, O(|V|^2) cost per augmentation
  6. // max flow: O(|V|^3) augmentations
  7. // min cost max flow: O(|V|^4 * MAX_EDGE_COST) augmentations
  8. // INPUT:
  9. // - graph, constructed using AddEdge()
  10. // - source
  11. // - sink
  12. // OUTPUT:
  13. // - (maximum flow value, minimum cost value)
  14. // - To obtain the actual flow, look at positive values only.
  15. struct MinCostMaxFlow {
  16. int N;
  17. VVL cap, flow, cost;
  18. VI found;
  19. VL dist, pi, width;
  20. VPII dad;
  21. MinCostMaxFlow(int N) :
  22. N(N), cap(N, VL(N)), flow(N, VL(N)), cost(N, VL(N)),
  23. found(N), dist(N), pi(N), width(N), dad(N) {}
  24. void AddEdge(int from, int to, L cap, L cost) {
  25. this->cap[from][to] = cap;
  26. this->cost[from][to] = cost;
  27. }
  28. void Relax(int s, int k, L cap, L cost, int dir) {
  29. L val = dist[s] + pi[s] - pi[k] + cost;
  30. if (cap && val < dist[k]) {
  31. dist[k] = val;
  32. dad[k] = make_pair(s, dir);
  33. width[k] = min(cap, width[s]);
  34. }
  35. }
  36. L Dijkstra(int s, int t) {
  37. fill(found.begin(), found.end(), false);
  38. fill(dist.begin(), dist.end(), INF);
  39. fill(width.begin(), width.end(), 0);
  40. dist[s] = 0;
  41. width[s] = INF;
  42. while (s != -1) {
  43. int best = -1;
  44. found[s] = true;
  45. for (int k = 0; k < N; k++) {
  46. if (found[k]) continue;
  47. Relax(s, k, cap[s][k] - flow[s][k], cost[s][k], 1);
  48. Relax(s, k, flow[k][s], -cost[k][s], -1);
  49. if (best == -1 || dist[k] < dist[best]) best = k;
  50. }
  51. s = best;
  52. }
  53. for (int k = 0; k < N; k++)
  54. pi[k] = min(pi[k] + dist[k], INF);
  55. return width[t];
  56. }
  57. pair<L, L> GetMaxFlow(int s, int t) {
  58. L totflow = 0, totcost = 0;
  59. while (L amt = Dijkstra(s, t)) {
  60. totflow += amt;
  61. for (int x = t; x != s; x = dad[x].first) {
  62. if (dad[x].second == 1) {
  63. flow[dad[x].first][x] += amt;
  64. totcost += amt * cost[dad[x].first][x];
  65. } else {
  66. flow[x][dad[x].first] -= amt;
  67. totcost -= amt * cost[x][dad[x].first];
  68. }
  69. }
  70. }
  71. return make_pair(totflow, totcost);
  72. }
  73. };