-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmax_flow.cc
62 lines (62 loc) · 1.36 KB
/
max_flow.cc
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
class Graph {
int V;
struct edge { int to, cap, rev; };
vector<vector<edge> > G;
VI level, iter;
void bfs() {
fill(ALL(level), -1);
queue<int> que;
level[source] = 0;
que.push(source);
while(!que.empty()) {
int v = que.front(); que.pop();
FOR(e, G[v]) {
if(e->cap > 0 && level[e->to] < 0) {
level[e->to] = level[v] + 1;
que.push(e->to);
}
}
}
}
int dfs(int v, int f) {
if(v == sink) return f;
for(int &i = iter[v]; i < SZ(G[v]); i++) {
edge &e = G[v][i];
if(e.cap > 0 && level[v] < level[e.to]) {
int d = dfs(e.to, min(f, e.cap));
if(d > 0) {
e.cap -= d;
G[e.to][e.rev].cap += d;
return d;
}
}
}
return 0;
}
public:
int source, sink;
Graph() { V = 0; source = addVertex(); sink = addVertex(); }
int addVertex() {
G.resize(V+1);
return V++;
}
void addEdge(int from, int to, int cap) {
G[from].push_back((edge){to, cap, (int)G[to].size()});
G[to].push_back((edge){from, 0, (int)G[from].size() - 1});
}
int maxFlow() {
int flow = 0;
level.resize(V);
iter.resize(V);
for (;;) {
bfs();
if(level[sink] < 0) return flow;
fill(ALL(iter), 0);
int f;
while((f = dfs(source, INT_MAX)) > 0) {
flow += f;
}
}
return flow;
}
};