1
+ #include < iostream>
2
+ #include < vector>
3
+ #include < climits>
4
+
5
+ /* *
6
+ * Dinic's algorithm is a strongly polynomial algorithm for computing
7
+ * the maximum flow in a flow network, conceived in 1970 by Yefim A. Dinitz.
8
+ * The algorithm runs in O(E*V^2) time and is similar to the Edmonds–Karp algorithm,
9
+ * which runs in O(V*E^2) time, in that it uses shortest augmenting paths.
10
+ *
11
+ * This implementation calculates maximum flow between the first and the last vertexes.
12
+ *
13
+ * @see https://en.wikipedia.org/wiki/Dinic%27s_algorithm
14
+ */
15
+
16
+ using namespace std ;
17
+
18
+ class graph {
19
+ public:
20
+
21
+ graph (unsigned vertexes) {
22
+ V = vertexes;
23
+ s = 0 ;
24
+ t = V - 1 ;
25
+ g.resize (V);
26
+ d.resize (V);
27
+ ptr.resize (V);
28
+ queue.resize (V);
29
+ }
30
+
31
+ int dinic () {
32
+ int flow = 0 ;
33
+ while (true ) {
34
+ if (!bfs ()) break ; // Break if vertex [t] is not reachable from vertex [s]
35
+ ptr.assign (V, 0 );
36
+ while (int pushed = dfs (s, INT_MAX))
37
+ flow += pushed;
38
+ }
39
+ return flow;
40
+ }
41
+
42
+ void addEdge (unsigned v1, unsigned v2, unsigned capacity) {
43
+ v1--; // Remove these decrements if
44
+ v2--; // vertexes are numbered from zero
45
+ edge e1 = {v1, v2, capacity, 0 };
46
+ edge e2 = {v2, v1, 0 , 0 };
47
+ g[v1].push_back ((int ) e.size ());
48
+ e.push_back (e1 );
49
+ g[v2].push_back ((int ) e.size ());
50
+ e.push_back (e2 );
51
+ }
52
+
53
+ private:
54
+ struct edge {
55
+ int a, b, capacity, flow;
56
+ };
57
+
58
+ unsigned V;
59
+ unsigned s, t;
60
+ vector<edge> e;
61
+ vector<vector<int >> g; // Graph adjacency list
62
+ vector<int > d; // d[u] is a shortest path from [s] to [u]
63
+ vector<int > ptr; // ptr[u] is a number of the first edge
64
+ // in [u] adjacency list, that was not removed
65
+ vector<int > queue;
66
+
67
+
68
+ bool bfs () {
69
+ int qhead = 0 , qtail = 0 ;
70
+ queue[qtail++] = s;
71
+ d.assign (V, -1 );
72
+ d[s] = 0 ;
73
+ while (qhead < qtail && d[t] == -1 ) {
74
+ int v = queue[qhead++];
75
+ for (size_t i = 0 ; i < g[v].size (); ++i) {
76
+ int id = g[v][i],
77
+ to = e[id].b ;
78
+ if (d[to] == -1 && e[id].flow < e[id].capacity ) {
79
+ queue[qtail++] = to;
80
+ d[to] = d[v] + 1 ;
81
+ }
82
+ }
83
+ }
84
+ return d[t] != -1 ;
85
+ }
86
+
87
+ // Finding the blocking flow
88
+ // `minflow` is a minimal capacity on the path of the level graph
89
+ int dfs (int v, int minflow) {
90
+ if (!minflow) return 0 ;
91
+ if (v == t) return minflow;
92
+ for (; ptr[v] < (int ) g[v].size (); ++ptr[v]) {
93
+ int id = g[v][ptr[v]],
94
+ to = e[id].b ;
95
+ if (d[to] != d[v] + 1 ) continue ;
96
+ int pushed = dfs (to, min (minflow, e[id].capacity - e[id].flow ));
97
+ if (pushed) {
98
+ e[id].flow += pushed;
99
+ e[id ^ 1 ].flow -= pushed;
100
+ return pushed;
101
+ }
102
+ }
103
+ return 0 ;
104
+ }
105
+ };
106
+
107
+ int main (int argc, char **argv) {
108
+ graph g (4 ); // Create graph with 4 vertexes
109
+
110
+ g.addEdge (1 , 2 , 1 ); // [1] --(1)--> [2]
111
+ g.addEdge (1 , 3 , 2 ); // [1] --(2)--> [3]
112
+ g.addEdge (3 , 2 , 1 ); // [3] --(1)--> [2]
113
+ g.addEdge (2 , 4 , 2 ); // [2] --(2)--> [4]
114
+ g.addEdge (3 , 4 , 1 ); // [3] --(1)--> [4]
115
+
116
+ cout << " Maximum flow: " << g.dinic ();
117
+ return 0 ;
118
+ }
0 commit comments