-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmax_flow_dinits.cpp
More file actions
89 lines (80 loc) · 2.38 KB
/
max_flow_dinits.cpp
File metadata and controls
89 lines (80 loc) · 2.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
template<typename weight_t, int maxv, int maxe>
struct DinitsMaxFlow {
const int S = maxv - 1;
const int T = maxv - 2;
struct Edge {
int to;
weight_t cap, flow;
} edges[maxe];
int ecount;
vector<int> g[maxv];
int dist[maxv];
int sid[maxv];
void reset() {
ecount = 0;
for (int i = 0; i < maxv; ++i)
g[i].clear();
}
void addDirectedEdge(int from, int to, weight_t cap) {
assert(0 <= from && from < maxv);
assert(0 <= to && to < maxv);
assert(ecount + 2 <= maxe);
edges[ecount].to = to;
edges[ecount].cap = cap;
edges[ecount].flow = 0;
g[from].push_back(ecount);
ecount++;
edges[ecount].to = from;
edges[ecount].cap = 0;
edges[ecount].flow = 0;
g[to].push_back(ecount);
ecount++;
}
int que[maxv];
bool bfs() {
memset(dist, 0x3f, sizeof(dist));
int fr = 0, bc = 1;
dist[S] = 0;
que[0] = S;
while (fr < bc) {
int v = que[fr++];
for (int eid = 0; eid < int(g[v].size()); ++eid) {
const int e = g[v][eid];
int u = edges[e].to;
if (edges[e].flow < edges[e].cap && dist[u] > dist[v] + 1) {
dist[u] = dist[v] + 1;
que[bc++] = u;
}
}
}
return (dist[T] < 0x3f3f3f3f);
}
weight_t dfs(int v, weight_t flow) {
if (v == T || flow == 0) return flow;
for (; sid[v] < int(g[v].size()); ++sid[v]) {
int e = g[v][sid[v]];
int u = edges[e].to;
if (dist[u] == dist[v] + 1 && edges[e].flow < edges[e].cap) {
flt res = dfs(u, min(flow, edges[e].cap - edges[e].flow));
if (res > 0) {
edges[e].flow += res;
edges[e ^ 1].flow -= res;
return res;
}
}
}
return 0;
}
weight_t go() {
flt res = 0;
while (bfs()) {
memset(sid, 0, sizeof(sid));
while (true) {
flt cur = dfs(S, weight_t(1e9));
if (cur == 0) break;
res += cur;
}
}
return res;
}
};