Advertisement
VladNitu

MaxFlowMinCost Library

May 2nd, 2023
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.91 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 = 1000;
  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() {
  32.         this->adj.resize(this->MAX_NODES);
  33.         this->node_count = 2 * N * TMAX + K + 2;
  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.     int min_cost_max_flow(int source, int sink) {
  68.         int total_cost = 0;
  69.         vector<Edge *> p;
  70.         while (find_path(source, sink, p)) {
  71.             int flow = INT_MAX;
  72.             for (int i = 0; i < p.size(); ++i)
  73.                 if (p[i]->c - p[i]->f < flow) flow = p[i]->c - p[i]->f;
  74.  
  75.             int cost = 0;
  76.             for (int i = 0; i < p.size(); ++i) {
  77.                 cost += p[i]->w;
  78.                 p[i]->f += flow;
  79.                 p[i]->r->f -= flow;
  80.             }
  81.             cost *= flow; //cost per flow
  82.             total_cost += cost;
  83.         }
  84.         return total_cost;
  85.     }
  86.  
  87.     void add_edge(int a, int b, int c, int w) {
  88.         Edge *e = new Edge(a, b, c, 0, w);
  89.         Edge *re = new Edge(b, a, 0, 0, -w);
  90.         e->r = re;
  91.         re->r = e;
  92.         adj[a].push_back(e);
  93.         adj[b].push_back(re);
  94.     }
  95.  
  96.     int run(int source, int sink) {
  97.         int ans = min_cost_max_flow(source, sink);
  98.         for (int i = 0; i < node_count; ++i) {
  99.             for (unsigned int j = 0; j < adj[i].size(); ++j)
  100.                 delete adj[i][j];
  101.             adj[i].clear();
  102.         }
  103.  
  104.         return ans;
  105.     }
  106. };
  107.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement