MinCostMaxFlow.cc 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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. //
  6. // Running time, O(|V|^2) cost per augmentation
  7. // max flow: O(|V|^3) augmentations
  8. // min cost max flow: O(|V|^4 * MAX_EDGE_COST) augmentations
  9. //
  10. // INPUT:
  11. // - graph, constructed using AddEdge()
  12. // - source
  13. // - sink
  14. //
  15. // OUTPUT:
  16. // - (maximum flow value, minimum cost value)
  17. // - To obtain the actual flow, look at positive values only.
  18. typedef vector<int> VI;
  19. typedef vector<VI> VVI;
  20. typedef long long L;
  21. typedef vector<L> VL;
  22. typedef vector<VL> VVL;
  23. typedef pair<int, int> PII;
  24. typedef vector<PII> VPII;
  25. const L INF = numeric_limits<L>::max() / 4;
  26. struct MinCostMaxFlow {
  27. int N;
  28. VVL cap, flow, cost;
  29. VI found;
  30. VL dist, pi, width;
  31. VPII dad;
  32. MinCostMaxFlow(int N) :
  33. N(N), cap(N, VL(N)), flow(N, VL(N)), cost(N, VL(N)),
  34. found(N), dist(N), pi(N), width(N), dad(N) {}
  35. void AddEdge(int from, int to, L cap, L cost) {
  36. this->cap[from][to] = cap;
  37. this->cost[from][to] = cost;
  38. }
  39. void Relax(int s, int k, L cap, L cost, int dir) {
  40. L val = dist[s] + pi[s] - pi[k] + cost;
  41. if (cap && val < dist[k]) {
  42. dist[k] = val;
  43. dad[k] = make_pair(s, dir);
  44. width[k] = min(cap, width[s]);
  45. }
  46. }
  47. L Dijkstra(int s, int t) {
  48. fill(found.begin(), found.end(), false);
  49. fill(dist.begin(), dist.end(), INF);
  50. fill(width.begin(), width.end(), 0);
  51. dist[s] = 0;
  52. width[s] = INF;
  53. while (s != -1) {
  54. int best = -1;
  55. found[s] = true;
  56. for (int k = 0; k < N; k++) {
  57. if (found[k]) continue;
  58. Relax(s, k, cap[s][k] - flow[s][k], cost[s][k], 1);
  59. Relax(s, k, flow[k][s], -cost[k][s], -1);
  60. if (best == -1 || dist[k] < dist[best]) best = k;
  61. }
  62. s = best;
  63. }
  64. for (int k = 0; k < N; k++)
  65. pi[k] = min(pi[k] + dist[k], INF);
  66. return width[t];
  67. }
  68. pair<L, L> GetMaxFlow(int s, int t) {
  69. L totflow = 0, totcost = 0;
  70. while (L amt = Dijkstra(s, t)) {
  71. totflow += amt;
  72. for (int x = t; x != s; x = dad[x].first) {
  73. if (dad[x].second == 1) {
  74. flow[dad[x].first][x] += amt;
  75. totcost += amt * cost[dad[x].first][x];
  76. } else {
  77. flow[x][dad[x].first] -= amt;
  78. totcost -= amt * cost[x][dad[x].first];
  79. }
  80. }
  81. }
  82. return make_pair(totflow, totcost);
  83. }
  84. };