Advertisement
VladNitu

maxflowmincost lib

May 3rd, 2023
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.02 KB | None | 0 0
  1. class Edge {
  2. public:
  3. Edge(int _a, int _b, int _c, int _f, int _w) {
  4. a = _a;
  5. b = _b;
  6. c = _c;
  7. f = _f;
  8. w = _w;
  9. }
  10.  
  11. ~Edge() {};
  12. int a; //from
  13. int b; //to
  14. int c; //capacity
  15. int f; //flow
  16. int w; //weight
  17. Edge *r;
  18.  
  19. };
  20.  
  21. class MaxFlowMinCost {
  22. public:
  23.  
  24. static const int MAX_NODES = 100000;
  25. const int MAX_DIST = 2000000; //do not choose INT_MAX because you are adding weights to it
  26. vector<vector<Edge *>> adj;
  27. int distances[MAX_NODES];
  28. Edge *parents[MAX_NODES];
  29. int node_count;
  30.  
  31. MaxFlowMinCost(int _nodes) {
  32. this->adj.resize(this->MAX_NODES);
  33. this->node_count = _nodes;
  34. }
  35.  
  36.  
  37. bool find_path(int from, int to, vector<Edge *> &output) // Assume no negative paths
  38. {
  39. fill(distances, distances + node_count, MAX_DIST);
  40. fill(parents, parents + node_count, (Edge *) 0);
  41. distances[from] = 0;
  42.  
  43. bool updated = true;
  44. while (updated) {
  45. updated = false;
  46. for (int j = 0; j < node_count; ++j)
  47. for (int k = 0; k < (int) adj[j].size(); ++k) {
  48. Edge *e = adj[j][k];
  49. if (e->f >= e->c) continue;
  50. if (distances[e->b] > distances[e->a] + e->w) {
  51. distances[e->b] = distances[e->a] + e->w;
  52. parents[e->b] = e;
  53. updated = true;
  54. }
  55. }
  56. }
  57. output.clear();
  58. if (distances[to] == MAX_DIST) return false;
  59. int cur = to;
  60. while (parents[cur]) {
  61. output.push_back(parents[cur]);
  62. cur = parents[cur]->a;
  63. }
  64. return true;
  65. }
  66.  
  67. pair<int, int> min_cost_max_flow(int source, int sink) {
  68. int total_cost = 0;
  69. int total_flow = 0;
  70. vector<Edge *> p;
  71. while (find_path(source, sink, p)) {
  72. int flow = INT_MAX;
  73. for (int i = 0; i < p.size(); ++i)
  74. if (p[i]->c - p[i]->f < flow) flow = p[i]->c - p[i]->f;
  75.  
  76. int cost = 0;
  77. for (int i = 0; i < p.size(); ++i) {
  78. cost += p[i]->w;
  79. p[i]->f += flow;
  80. p[i]->r->f -= flow;
  81. }
  82. total_flow += flow;
  83. cost *= flow; //cost per flow
  84. total_cost += cost;
  85. }
  86. return {total_flow, total_cost};
  87. }
  88.  
  89. void add_edge(int a, int b, int c, int w) {
  90. Edge *e = new Edge(a, b, c, 0, w);
  91. Edge *re = new Edge(b, a, 0, 0, -w);
  92. e->r = re;
  93. re->r = e;
  94. adj[a].push_back(e);
  95. adj[b].push_back(re);
  96. }
  97.  
  98. int run(int source, int sink) {
  99. const auto [max_flow, min_cost] = min_cost_max_flow(source, sink);
  100. for (int i = 0; i < node_count; ++i) {
  101. for (unsigned int j = 0; j < adj[i].size(); ++j)
  102. delete adj[i][j];
  103. adj[i].clear();
  104. }
  105.  
  106. return max_flow;
  107. }
  108. };
  109.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement