Pattern Reference
Network Flow
"Ford-Fulkerson, Edmonds-Karp, Dinic's, max-flow min-cut, circulation."
Loading...
Deep Dive Tutorial
Network flow models problems where you want to route maximum "stuff" (data, goods, people) through a network with capacities. The key insight: max-flow equals min-cut — the bottleneck is always some set of edges whose total capacity limits all paths from source to sink. Dinic's algorithm uses BFS to build a "level graph" then finds blocking flows layer by layer — much faster than naive augmenting paths.
Dinic's max-flow algorithm
class MaxFlow {
constructor(n) {
this.n = n;
this.graph = Array.from({length: n}, () => []);
}
addEdge(u, v, cap) {
this.graph[u].push({to: v, cap, rev: this.graph[v].length});
this.graph[v].push({to: u, cap: 0, rev: this.graph[u].length - 1});
}
bfs(s, t, level) {
level.fill(-1); level[s] = 0;
const queue = [s]; let i = 0;
while (i < queue.length) {
const u = queue[i++];
for (const e of this.graph[u]) {
if (e.cap > 0 && level[e.to] < 0) {
level[e.to] = level[u] + 1;
queue.push(e.to);
}
}
}
return level[t] >= 0;
}
dfs(u, t, f, level, iter) {
if (u === t) return f;
for (; iter[u] < this.graph[u].length; iter[u]++) {
const e = this.graph[u][iter[u]];
if (e.cap > 0 && level[e.to] === level[u] + 1) {
const d = this.dfs(e.to, t, Math.min(f, e.cap), level, iter);
if (d > 0) {
e.cap -= d;
this.graph[e.to][e.rev].cap += d;
return d;
}
}
}
return 0;
}
maxflow(s, t) {
const level = new Array(this.n), iter = new Array(this.n);
let flow = 0;
while (this.bfs(s, t, level)) {
iter.fill(0);
let f;
while ((f = this.dfs(s, t, Infinity, level, iter)) > 0) flow += f;
}
return flow;
}
}Worked Problems
waves
Max-flow min-cut theorem: max flow from s to t = min capacity of any s-t cut.
Algorithm selection:
- Edmonds-Karp (BFS augmenting): O(VE²) — simple to implement
- Dinic's: O(V²E), O(E√V) for unit capacity — fast in practice
- For bipartite matching: any max-flow works; O(E√V) with Hopcroft-Karp
Modeling tricks:
- Node capacity: split node v into v_in → v_out with edge capacity = node limit
- Bidirectional edge: add both directions with their capacities
- Lower bounds on flow: shift using supply/demand at nodes
Applications: bipartite matching (König's: max matching = total - max flow complement), project selection (each project profits/costs modeled as source/sink edges), circulation with demands.
Algorithm selection:
- Edmonds-Karp (BFS augmenting): O(VE²) — simple to implement
- Dinic's: O(V²E), O(E√V) for unit capacity — fast in practice
- For bipartite matching: any max-flow works; O(E√V) with Hopcroft-Karp
Modeling tricks:
- Node capacity: split node v into v_in → v_out with edge capacity = node limit
- Bidirectional edge: add both directions with their capacities
- Lower bounds on flow: shift using supply/demand at nodes
Applications: bipartite matching (König's: max matching = total - max flow complement), project selection (each project profits/costs modeled as source/sink edges), circulation with demands.