keverman

Dinic's Algorithm (maxflow)

May 6th, 2019 (edited)
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.06 KB | None | 0 0
  1.  
  2. vector<int> level, edge_begin;
  3. vector<vector<edge>> edges;
  4.  
  5. // Simple BFS calculating distance of each vertex from the source
  6. bool level_bfs(int s, int t)
  7. {
  8.     fill(level.begin(), level.end(), -1);
  9.     level[s] = 0;
  10.  
  11.     queue<int> Q;
  12.     Q.push(s);
  13.  
  14.     while (!Q.empty())
  15.     {
  16.         int from = Q.front();
  17.         Q.pop();
  18.  
  19.         for (edge& e : edges[from])
  20.             if (level[e.to] < 0 && e.flow < e.capacity)
  21.             {
  22.                 level[e.to] = level[from] + 1;
  23.                 Q.push(e.to);
  24.             }
  25.     }
  26.  
  27.     // Return true if the target is reachable from the source
  28.     return level[t] != -1;
  29. }
  30.  
  31. // Recursion to push flow from a parent vertex to the target
  32. int push_flow(int from, int t, int flow)
  33. {
  34.     if (from == t)
  35.         return flow;
  36.  
  37.     // Iterate untraversed edges to find a subpath to the target with positive capacity
  38.     for (; edge_begin[from] < edges[from].size(); edge_begin[from]++)
  39.     {
  40.         edge& e = edges[from][edge_begin[from]];
  41.  
  42.         // Ascertain foward motion and sufficient capcity
  43.         if (level[e.to] == level[from] + 1 && e.flow < e.capacity)
  44.         {
  45.             int subpath_flow = push_flow(e.to, t, min(flow, e.capacity - e.flow));
  46.  
  47.             // Update the flow with the positive capacity subpath, if such has been found
  48.             if (subpath_flow > 0)
  49.             {
  50.                 e.flow += subpath_flow;
  51.                 edges[e.to][e.rev].flow -= subpath_flow;
  52.                 return subpath_flow;
  53.             }
  54.         }
  55.     }
  56.  
  57.     // No positive capacity subpath found
  58.     return 0;
  59. }
  60.  
  61. // Find the maximum flow of a directed graph
  62. int Dinic(int s, int t)
  63. {
  64.     // Assumes source can't be the target
  65.     int result = 0;
  66.  
  67.     // Keep pushing flows until unable to reach the target from the source
  68.     while (level_bfs(s, t))
  69.     {
  70.         // Reset current edge iteration for all vertexes
  71.         fill(edge_begin.begin(), edge_begin.end(), 0);
  72.  
  73.         while (int flow = push_flow(s, t, INT_MAX))
  74.             result += flow;
  75.     }
  76.  
  77.     return result;
  78. }
Add Comment
Please, Sign In to add comment