leoanjos

Dinic

Feb 13th, 2023
1,343
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.09 KB | None | 0 0
  1. template<typename T = int>
  2. struct MaxFlow {
  3. private:
  4.     struct Edge {
  5.         int to;
  6.         T cap;
  7.  
  8.         Edge(int to, T cap) {
  9.             this->to = to;
  10.             this->cap = cap;
  11.         }
  12.     };
  13.  
  14.     int n, src, snk;
  15.     vector<Edge> edges;
  16.     vector<vector<int>> ids;
  17.     vector<int> depth, first;
  18.  
  19. public:
  20.     MaxFlow(int n) {
  21.         this->n = n;
  22.         ids.assign(n, vector<int>());
  23.     }
  24.  
  25.     void add_edge(int u, int v, T cap) {
  26.         int m = edges.size();
  27.  
  28.         edges.push_back(Edge(v, cap));
  29.         ids[u].push_back(m);
  30.  
  31.         edges.push_back(Edge(u, 0));
  32.         ids[v].push_back(m + 1);
  33.     }
  34.  
  35.     T max_flow(int src, int snk) {
  36.         const T INF = numeric_limits<T>::max();
  37.  
  38.         this->src = src;
  39.         this->snk = snk;
  40.  
  41.         T ans = 0;
  42.         while (get_depths()) {
  43.             T flow;
  44.             first.assign(n, 0);
  45.  
  46.             while ((flow = find_path(src, INF)) > 0)
  47.                 ans += flow;
  48.         }
  49.  
  50.         return ans;
  51.     }
  52.  
  53. private:
  54.     bool get_depths() {
  55.         depth.assign(n, -1);
  56.         depth[src] = 0;
  57.  
  58.         queue<int> aux;
  59.         aux.push(src);
  60.  
  61.         while (!aux.empty()) {
  62.             int v = aux.front(); aux.pop();
  63.             for (auto id: ids[v]) {
  64.                 Edge &e = edges[id];
  65.                 if (e.cap > 0 && depth[e.to] == -1) {
  66.                     aux.push(e.to);
  67.                     depth[e.to] = depth[v] + 1;
  68.                 }
  69.             }
  70.         }
  71.  
  72.         return depth[snk] != -1;
  73.     }
  74.  
  75.     T find_path(int v, T flow) {
  76.         if (flow == 0) return 0;
  77.         if (v == snk) return flow;
  78.  
  79.         while (first[v] < (int) ids[v].size()) {
  80.             int id = ids[v][first[v]++];
  81.             Edge &e = edges[id];
  82.  
  83.             if (depth[e.to] == depth[v] + 1) {
  84.                 T curr = find_path(e.to, min(flow, e.cap));
  85.                 if (curr > 0) {
  86.                     edges[id].cap -= curr;
  87.                     edges[id ^ 1].cap += curr;
  88.                     return curr;
  89.                 }
  90.             }
  91.         }
  92.  
  93.         return 0;
  94.     }
  95. };
Advertisement
Add Comment
Please, Sign In to add comment