MinCostMaxFlow.cc 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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. #include <cmath>
  19. #include <vector>
  20. #include <iostream>
  21. using namespace std;
  22. typedef vector<int> VI;
  23. typedef vector<VI> VVI;
  24. typedef long long L;
  25. typedef vector<L> VL;
  26. typedef vector<VL> VVL;
  27. typedef pair<int, int> PII;
  28. typedef vector<PII> VPII;
  29. const L INF = numeric_limits<L>::max() / 4;
  30. struct MinCostMaxFlow {
  31. int N;
  32. VVL cap, flow, cost;
  33. VI found;
  34. VL dist, pi, width;
  35. VPII dad;
  36. MinCostMaxFlow(int N) :
  37. N(N), cap(N, VL(N)), flow(N, VL(N)), cost(N, VL(N)),
  38. found(N), dist(N), pi(N), width(N), dad(N) {}
  39. void AddEdge(int from, int to, L cap, L cost) {
  40. this->cap[from][to] = cap;
  41. this->cost[from][to] = cost;
  42. }
  43. void Relax(int s, int k, L cap, L cost, int dir) {
  44. L val = dist[s] + pi[s] - pi[k] + cost;
  45. if (cap && val < dist[k]) {
  46. dist[k] = val;
  47. dad[k] = make_pair(s, dir);
  48. width[k] = min(cap, width[s]);
  49. }
  50. }
  51. L Dijkstra(int s, int t) {
  52. fill(found.begin(), found.end(), false);
  53. fill(dist.begin(), dist.end(), INF);
  54. fill(width.begin(), width.end(), 0);
  55. dist[s] = 0;
  56. width[s] = INF;
  57. while (s != -1) {
  58. int best = -1;
  59. found[s] = true;
  60. for (int k = 0; k < N; k++) {
  61. if (found[k]) continue;
  62. Relax(s, k, cap[s][k] - flow[s][k], cost[s][k], 1);
  63. Relax(s, k, flow[k][s], -cost[k][s], -1);
  64. if (best == -1 || dist[k] < dist[best]) best = k;
  65. }
  66. s = best;
  67. }
  68. for (int k = 0; k < N; k++)
  69. pi[k] = min(pi[k] + dist[k], INF);
  70. return width[t];
  71. }
  72. pair<L, L> GetMaxFlow(int s, int t) {
  73. L totflow = 0, totcost = 0;
  74. while (L amt = Dijkstra(s, t)) {
  75. totflow += amt;
  76. for (int x = t; x != s; x = dad[x].first) {
  77. if (dad[x].second == 1) {
  78. flow[dad[x].first][x] += amt;
  79. totcost += amt * cost[dad[x].first][x];
  80. } else {
  81. flow[x][dad[x].first] -= amt;
  82. totcost -= amt * cost[x][dad[x].first];
  83. }
  84. }
  85. }
  86. return make_pair(totflow, totcost);
  87. }
  88. };