Advertisement
BotByte

Dinic.cpp

Apr 23rd, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.32 KB | None | 0 0
  1. Below is c++ implementation of Dinic’s algorithm:
  2. // C++ implementation of Dinic's Algorithm
  3. #include<bits/stdc++.h>
  4. using namespace std;
  5.  
  6. // A structure to represent a edge between
  7. // two vertex
  8. struct Edge
  9. {
  10.     int v ;  // Vertex v (or "to" vertex)
  11.              // of a directed edge u-v. "From"
  12.              // vertex u can be obtained using
  13.              // index in adjacent array.
  14.  
  15.     int flow ; // flow of data in edge
  16.  
  17.     int C;    // capacity
  18.  
  19.     int rev ; // To store index of reverse
  20.               // edge in adjacency list so that
  21.               // we can quickly find it.
  22. };
  23.  
  24. // Residual Graph
  25. class Graph
  26. {
  27.     int V; // number of vertex
  28.     int *level ; // stores level of a node
  29.     vector< Edge > *adj;
  30. public :
  31.     Graph(int V)
  32.     {
  33.         adj = new vector<Edge>[V];
  34.         this->V = V;
  35.         level = new int[V];
  36.     }
  37.  
  38.     // add edge to the graph
  39.     void addEdge(int u, int v, int C)
  40.     {
  41.         // Forward edge : 0 flow and C capacity
  42.         Edge a{v, 0, C, adj[v].size()};
  43.  
  44.         // Back edge : 0 flow and 0 capacity
  45.         Edge b{u, 0, 0, adj[u].size()};
  46.  
  47.         adj[u].push_back(a);
  48.         adj[v].push_back(b); // reverse edge
  49.     }
  50.  
  51.     bool BFS(int s, int t);
  52.     int sendFlow(int s, int flow, int t, int ptr[]);
  53.     int DinicMaxflow(int s, int t);
  54. };
  55.  
  56. // Finds if more flow can be sent from s to t.
  57. // Also assigns levels to nodes.
  58. bool Graph::BFS(int s, int t)
  59. {
  60.     for (int i = 0 ; i < V ; i++)
  61.         level[i] = -1;
  62.  
  63.     level[s] = 0;  // Level of source vertex
  64.  
  65.     // Create a queue, enqueue source vertex
  66.     // and mark source vertex as visited here
  67.     // level[] array works as visited array also.
  68.     list< int > q;
  69.     q.push_back(s);
  70.  
  71.     vector<Edge>::iterator i ;
  72.     while (!q.empty())
  73.     {
  74.         int u = q.front();
  75.         q.pop_front();
  76.         for (i = adj[u].begin(); i != adj[u].end(); i++)
  77.         {
  78.             Edge &e = *i;
  79.             if (level[e.v] < 0  && e.flow < e.C)
  80.             {
  81.                 // Level of current vertex is,
  82.                 // level of parent + 1
  83.                 level[e.v] = level[u] + 1;
  84.  
  85.                 q.push_back(e.v);
  86.             }
  87.         }
  88.     }
  89.  
  90.     // IF we can not reach to the sink we
  91.     // return false else true
  92.     return level[t] < 0 ? false : true ;
  93. }
  94.  
  95. // A DFS based function to send flow after BFS has
  96. // figured out that there is a possible flow and
  97. // constructed levels. This function called multiple
  98. // times for a single call of BFS.
  99. // flow : Current flow send by parent function call
  100. // start[] : To keep track of next edge to be explored.
  101. //           start[i] stores  count of edges explored
  102. //           from i.
  103. //  u : Current vertex
  104. //  t : Sink
  105. int Graph::sendFlow(int u, int flow, int t, int start[])
  106. {
  107.     // Sink reached
  108.     if (u == t)
  109.         return flow;
  110.  
  111.     // Traverse all adjacent edges one -by - one.
  112.     for (  ; start[u] < adj[u].size(); start[u]++)
  113.     {
  114.         // Pick next edge from adjacency list of u
  115.         Edge &e = adj[u][start[u]];
  116.                                      
  117.         if (level[e.v] == level[u]+1 && e.flow < e.C)
  118.         {
  119.             // find minimum flow from u to t
  120.             int curr_flow = min(flow, e.C - e.flow);
  121.  
  122.             int temp_flow = sendFlow(e.v, curr_flow, t, start);
  123.  
  124.             // flow is greater than zero
  125.             if (temp_flow > 0)
  126.             {
  127.                 // add flow  to current edge
  128.                 e.flow += temp_flow;
  129.  
  130.                 // subtract flow from reverse edge
  131.                 // of current edge
  132.                 adj[e.v][e.rev].flow -= temp_flow;
  133.                 return temp_flow;
  134.             }
  135.         }
  136.     }
  137.  
  138.     return 0;
  139. }
  140.  
  141. // Returns maximum flow in graph
  142. int Graph::DinicMaxflow(int s, int t)
  143. {
  144.     // Corner case
  145.     if (s == t)
  146.         return -1;
  147.  
  148.     int total = 0;  // Initialize result
  149.  
  150.     // Augment the flow while there is path
  151.     // from source to sink
  152.     while (BFS(s, t) == true)
  153.     {
  154.         // store how many edges are visited
  155.         // from V { 0 to V }
  156.         int *start = new int[V+1];
  157.  
  158.         // while flow is not zero in graph from S to D
  159.         while (int flow = sendFlow(s, INT_MAX, t, start))
  160.  
  161.             // Add path flow to overall flow
  162.             total += flow;
  163.     }
  164.  
  165.     // return maximum flow
  166.     return total;
  167. }
  168.  
  169. // Driver program to test above functions
  170. int main()
  171. {
  172.     Graph g(6);
  173.     g.addEdge(0, 1, 16 );
  174.     g.addEdge(0, 2, 13 );
  175.     g.addEdge(1, 2, 10 );
  176.     g.addEdge(1, 3, 12 );
  177.     g.addEdge(2, 1, 4 );
  178.     g.addEdge(2, 4, 14);
  179.     g.addEdge(3, 2, 9 );
  180.     g.addEdge(3, 5, 20 );
  181.     g.addEdge(4, 3, 7 );
  182.     g.addEdge(4, 5, 4);
  183.  
  184.     // next exmp
  185.     /*g.addEdge(0, 1, 3 );
  186.       g.addEdge(0, 2, 7 ) ;
  187.       g.addEdge(1, 3, 9);
  188.       g.addEdge(1, 4, 9 );
  189.       g.addEdge(2, 1, 9 );
  190.       g.addEdge(2, 4, 9);
  191.       g.addEdge(2, 5, 4);
  192.       g.addEdge(3, 5, 3);
  193.       g.addEdge(4, 5, 7 );
  194.       g.addEdge(0, 4, 10);
  195.  
  196.      // next exp
  197.      g.addEdge(0, 1, 10);
  198.      g.addEdge(0, 2, 10);
  199.      g.addEdge(1, 3, 4 );
  200.      g.addEdge(1, 4, 8 );
  201.      g.addEdge(1, 2, 2 );
  202.      g.addEdge(2, 4, 9 );
  203.      g.addEdge(3, 5, 10 );
  204.      g.addEdge(4, 3, 6 );
  205.      g.addEdge(4, 5, 10 ); */
  206.  
  207.     cout << "Maximum flow " << g.DinicMaxflow(0, 5);
  208.     return 0;
  209. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement