Skip to content

Commit 20adfe4

Browse files
Merge pull request #565 from mysterion/master
added dinic's algo
2 parents f5e7c1d + d8bb22d commit 20adfe4

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed
+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#include <vector>
2+
#include <queue>
3+
4+
/*
5+
usage : include this file in your project
6+
If you want to test create an instance of the struct Dinic
7+
pass in the appropriate arguments
8+
call the flow() function
9+
*/
10+
11+
using namespace std;
12+
13+
struct FlowEdge {
14+
int v, u;
15+
long long cap, flow = 0;
16+
FlowEdge(int v, int u, long long cap) : v(v), u(u), cap(cap) {}
17+
};
18+
19+
struct Dinic {
20+
const long long flow_inf = 1e18;
21+
vector<FlowEdge> edges;
22+
vector<vector<int>> adj;
23+
int n, m = 0;
24+
int s, t;
25+
vector<int> level, ptr;
26+
queue<int> q;
27+
28+
Dinic(int n, int s, int t) : n(n), s(s), t(t) {
29+
adj.resize(n);
30+
level.resize(n);
31+
ptr.resize(n);
32+
}
33+
34+
void add_edge(int v, int u, long long cap) {
35+
edges.emplace_back(v, u, cap);
36+
edges.emplace_back(u, v, 0);
37+
adj[v].push_back(m);
38+
adj[u].push_back(m + 1);
39+
m += 2;
40+
}
41+
42+
bool bfs() {
43+
while (!q.empty()) {
44+
int v = q.front();
45+
q.pop();
46+
for (int id : adj[v]) {
47+
if (edges[id].cap - edges[id].flow < 1)
48+
continue;
49+
if (level[edges[id].u] != -1)
50+
continue;
51+
level[edges[id].u] = level[v] + 1;
52+
q.push(edges[id].u);
53+
}
54+
}
55+
return level[t] != -1;
56+
}
57+
58+
long long dfs(int v, long long pushed) {
59+
if (pushed == 0)
60+
return 0;
61+
if (v == t)
62+
return pushed;
63+
for (int& cid = ptr[v]; cid < (int)adj[v].size(); cid++) {
64+
int id = adj[v][cid];
65+
int u = edges[id].u;
66+
if (level[v] + 1 != level[u] || edges[id].cap - edges[id].flow < 1)
67+
continue;
68+
long long tr = dfs(u, min(pushed, edges[id].cap - edges[id].flow));
69+
if (tr == 0)
70+
continue;
71+
edges[id].flow += tr;
72+
edges[id ^ 1].flow -= tr;
73+
return tr;
74+
}
75+
return 0;
76+
}
77+
78+
long long flow() {
79+
long long f = 0;
80+
while (true) {
81+
fill(level.begin(), level.end(), -1);
82+
level[s] = 0;
83+
q.push(s);
84+
if (!bfs())
85+
break;
86+
fill(ptr.begin(), ptr.end(), 0);
87+
while (long long pushed = dfs(s, flow_inf)) {
88+
f += pushed;
89+
}
90+
}
91+
return f;
92+
}
93+
};

0 commit comments

Comments
 (0)