matbensch

Dinic C++

Jan 25th, 2023 (edited)
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.05 KB | None | 0 0
  1. // taken from https://cp-algorithms.com/graph/dinic.html
  2. #include <iostream>
  3. #include <vector>
  4. #include <queue>
  5.  
  6. using namespace std;
  7.  
  8. struct FlowEdge {
  9.     int v, u;
  10.     long long cap, flow = 0;
  11.     FlowEdge(int v, int u, long long cap) : v(v), u(u), cap(cap) {}
  12. };
  13.  
  14. struct Dinic {
  15.     const long long flow_inf = 1e18;
  16.     vector<FlowEdge> edges;
  17.     vector<vector<int>> adj;
  18.     int n, m = 0;
  19.     int s, t;
  20.     vector<int> level, ptr;
  21.     queue<int> q;
  22.  
  23.     Dinic(int n, int s, int t) : n(n), s(s), t(t) {
  24.         adj.resize(n);
  25.         level.resize(n);
  26.         ptr.resize(n);
  27.     }
  28.  
  29.     void add_edge(int v, int u, long long cap) {
  30.         edges.emplace_back(v, u, cap);
  31.         edges.emplace_back(u, v, 0);
  32.         adj[v].push_back(m);
  33.         adj[u].push_back(m + 1);
  34.         m += 2;
  35.     }
  36.  
  37.     bool bfs() {
  38.         while (!q.empty()) {
  39.             int v = q.front();
  40.             q.pop();
  41.             for (int id : adj[v]) {
  42.                 if (edges[id].cap - edges[id].flow < 1)
  43.                     continue;
  44.                 if (level[edges[id].u] != -1)
  45.                     continue;
  46.                 level[edges[id].u] = level[v] + 1;
  47.                 q.push(edges[id].u);
  48.             }
  49.         }
  50.         return level[t] != -1;
  51.     }
  52.  
  53.     long long dfs(int v, long long pushed) {
  54.         if (pushed == 0)
  55.             return 0;
  56.         if (v == t)
  57.             return pushed;
  58.         for (int& cid = ptr[v]; cid < (int)adj[v].size(); cid++) {
  59.             int id = adj[v][cid];
  60.             int u = edges[id].u;
  61.             if (level[v] + 1 != level[u] || edges[id].cap - edges[id].flow < 1)
  62.                 continue;
  63.             long long tr = dfs(u, min(pushed, edges[id].cap - edges[id].flow));
  64.             if (tr == 0)
  65.                 continue;
  66.             edges[id].flow += tr;
  67.             edges[id ^ 1].flow -= tr;
  68.             return tr;
  69.         }
  70.         return 0;
  71.     }
  72.  
  73.     long long flow() {
  74.         long long f = 0;
  75.         while (true) {
  76.             fill(level.begin(), level.end(), -1);           // reset level assignments
  77.             level[s] = 0;                                   // source level is 0
  78.             q.push(s);                                      // push s to bfs queue
  79.             if (!bfs())                                     // if dist(t)=INF, we are done
  80.                 break;
  81.             fill(ptr.begin(), ptr.end(), 0);                // pointers speed up DFS, read more at cp-algorithms.com/graph/dinic.html
  82.             while (long long pushed = dfs(s, flow_inf)) {   // while we can find a valid path, augment it and ...
  83.                 f += pushed;                                // ... increment max flow
  84.             }                                              
  85.         }
  86.         return f;
  87.     }
  88. };
  89.  
  90. int main()
  91. {
  92.     Dinic mf(6,0,5);
  93.     mf.add_edge(0,1,10);
  94.     mf.add_edge(0,2,10);
  95.     mf.add_edge(1,2,2);
  96.     mf.add_edge(1,3,4);
  97.     mf.add_edge(1,4,8);
  98.     mf.add_edge(2,4,9);
  99.     mf.add_edge(3,5,10);
  100.     mf.add_edge(4,3,6);
  101.     mf.add_edge(4,5,10);
  102.  
  103.     cout << "Max Flow: " << mf.flow() << '\n';
  104. }
Advertisement
Add Comment
Please, Sign In to add comment