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
|
struct edge {
int from, to;
ll f, c;
};
vector<edge> edges;
vector<vector<int>> adjlist, hs;
vector<ll> ec;
vector<int> cur, H;
void addEdge(int from, int to, ll c) {
adjlist[from].push_back(sz(edges));
edges.push_back({from, to, 0, c});
adjlist[to].push_back(sz(edges));
edges.push_back({to, from, 0, 0});
}
void addFlow(int id, ll f) {
if (ec[edges[id].to] == 0 && f > 0)
hs[H[edges[id].to]].push_back(edges[id].to);
edges[id].f += f;
edges[id^1].f -= f;
ec[edges[id].to] += f;
ec[edges[id].from] -= f;
}
ll maxFlow(int s, int t) {
int n = sz(adjlist);
hs.assign(2*n, {});
ec.assign(n, 0);
cur.assign(n, 0);
H.assign(n, 0);
H[s] = n;
ec[t] = 1;//never set t to active...
vector<int> co(2*n);
co[0] = n - 1;
for (int id : adjlist[s]) addFlow(id, edges[id].c);
for (int hi = 0;;) {
while (hs[hi].empty()) if (!hi--) return -ec[s];
int u = hs[hi].back();
hs[hi].pop_back();
while (ec[u] > 0) {
if (cur[u] == sz(adjlist[u])) {
H[u] = 2*n;
for (int i = 0; i < sz(adjlist[u]); i++) {
int id = adjlist[u][i];
if (edges[id].c - edges[id].f > 0 &&
H[u] > H[edges[id].to] + 1) {
H[u] = H[edges[id].to] + 1;
cur[u] = i;
}}
co[H[u]]++;
if (!--co[hi] && hi < n) {
for (int i = 0; i < n; i++) {
if (hi < H[i] && H[i] < n) {
co[H[i]]--;
H[i] = n + 1;
}}}
hi = H[u];
} else {
auto e = edges[adjlist[u][cur[u]]];
if (e.c - e.f > 0 && H[u] == H[e.to] + 1) {
addFlow(adjlist[u][cur[u]], min(ec[u], e.c - e.f));
} else {
cur[u]++;
}}}}}
|