Skip to content

Commit d587dc3

Browse files
Merge pull request matthewsamuel95#143 from egormkn/master
[Network Flow] Dinic's algorithm added
2 parents 2a74cd4 + c4d589e commit d587dc3

File tree

1 file changed

+118
-0
lines changed

1 file changed

+118
-0
lines changed

NetworkFlow/Dinic/Dinic.cpp

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
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

Comments
 (0)