Worked examples — Network flow — max-flow min-cut theorem, Ford-Fulkerson, Edmonds-Karp
Before anything, one picture to fix the vocabulary we reuse everywhere.

Recall Vocabulary refresher (from the parent)
- Capacity ::: the max water a pipe can carry.
- Flow ::: how much water actually flows, with and water-in = water-out at every middle node.
- Residual capacity ::: leftover room forward, plus a backward edge of capacity that lets you take water back.
- Augmenting path ::: any path in the residual graph; its bottleneck = smallest residual capacity along it.
- Cut ::: split the nodes so ; its capacity counts only forward edges.
The scenario matrix
Every worked example below is tagged with the cell it covers. Together they hit all of them.
| Cell | Case class | What makes it tricky | Example |
|---|---|---|---|
| A | Plain integer network | nothing — the baseline | Ex 1 |
| B | Greedy trap needing a backward edge | naive DFS gets stuck below optimum | Ex 2 |
| C | Zero / degenerate input (a cut edge of cap 0, or disconnected from ) | max flow ; is that a bug? | Ex 3 |
| D | Tie / multiple min cuts | more than one cut achieves the minimum | Ex 4 |
| E | Path-choice matters: bad order = many iterations, good order = few (Ford-Fulkerson vs Edmonds-Karp) | value-dependent blow-up | Ex 5 |
| F | Limiting behaviour: huge capacities, worst-case iteration count | why capacity-independence matters | Ex 6 |
| G | Word problem (real-world modelling) | you must build the graph first | Ex 7 |
| H | Exam twist: node capacities / bipartite matching reduction | reduce a new problem to max flow | Ex 8 |
Example 1 — the baseline (Cell A)

- Total capacity out of is . So max flow (nothing can enter faster than it leaves ). Why this step? It gives an instant upper bound — the cut already caps the answer. If we can reach 5 we are done.
- Push path , bottleneck . Now is saturated. Why this step? is the limiter on this route; taking it first uses the cheap capacity.
- Push path , bottleneck . Now is saturated. Why this step? Independent route, no conflict with step 2.
- Push path . Residuals: has left, , . Bottleneck . Why this step? We still have unit of unused; route it through to .
- Total . No residual edge remains, so no augmenting path exists.
Verify: the cut has forward capacity . Flow cut optimal by the theorem. ✔
Example 2 — the greedy trap (Cell B)

- Greedy push , bottleneck . Now are saturated. . Why this step? This is exactly the "wrong" first choice — it blocks the two direct routes.
- Panic check: needs incoming flow at , but is full. needs outgoing at , but is full. Looks stuck. Why this step? To see why greedy-without-backward-edges fails.
- Look at the residual graph: committing created a backward edge of capacity . New path: using (1), backward (1), (1). Bottleneck . Why this step? The backward edge says "I can undo up to unit of " — that frees and .
- Push it. . Net effect: dropped back to ; flow now goes and .
Verify: cut gives . Flow cut optimal. Backward edge rescued us. ✔ (See Menger's Theorem: = number of edge-disjoint paths.)
Example 3 — zero / degenerate input (Cell C)
- (3a): The only route passes through the -capacity edge . Its residual capacity is , so no augmenting path exists from the start. Why this step? A -capacity edge is as if the edge is absent — the definition allows it explicitly ( "if no edge").
- (3a) answer: max flow . The min cut is , . Theorem holds: . Why this step? Confirms is a legitimate optimum, not an error.
- (3b): can fill , but has no outgoing edge to . By conservation, cannot accumulate water, so nothing can flow into either. Max flow . Why this step? Conservation forbids a "dead-end pool" — flow into must equal flow out, which is .
- (3b) cut: . Forward edges : none. So . Again .
Verify: In both sub-cases . A max flow of means is unreachable from in the residual graph — perfectly valid, never a bug. ✔
Example 4 — ties: multiple min cuts (Cell D)

- Push (bottleneck ) and (bottleneck ). . Why this step? Two independent chains, no interaction — saturate both.
- Enumerate cuts. Each middle node can be on the side or side, giving cuts:
- : forward edges → capacity .
- : forward → .
- : forward → .
- : forward → . Why this step? We list every partition with to find which are minimal.
- All four cuts have capacity . So the min cut is not unique — every cut here is a min cut.
Verify: equals the minimum (indeed the only) cut capacity . Ties are normal; the theorem promises a min cut equals max flow, not a unique one. ✔
Example 5 — path choice changes the work (Cell E)

- Bad Ford-Fulkerson: always pick a path through the middle edge (or its backward twin).
- Iter 1: , bottleneck . Push .
- Iter 2: (backward ), bottleneck . Push .
- Each iteration only moves the middle edge by , so it takes iterations to reach . Why this step? The bottleneck is always the tiny middle edge; a careless chooser keeps threading it.
- Edmonds-Karp (BFS shortest path): BFS finds the fewest-edge path first.
- Path (length ), bottleneck . Push .
- Path (length ), bottleneck . Push .
- Done: in augmentations — BFS never touches the middle edge. Why this step? Shortest paths avoid the useless detour, so the bound is independent of the s.
Verify: both reach max flow (cut : ). Bad order: iterations. Edmonds-Karp: iterations. Same answer, wildly different cost — that's why BFS path selection matters. ✔
Example 6 — limiting behaviour, huge capacities (Cell F)
- (a) Max flow . The two direct paths and each carry ; the middle edge is never needed. Cut gives . Why this step? The min cut is the two source edges; the middle edge contributes nothing to any forward boundary that beats .
- (b) Worst Ford-Fulkerson: the zig-zag order pushes unit per iteration → iterations. This is — it scales with the capacity value. For irrational capacities the analogous construction may never terminate. Why this step? Shows the failure mode: value-dependent, and unbounded in the limit .
- (b) Edmonds-Karp: still just augmentations (both length- direct paths), independent of . Its bound has no in it. Why this step? This is the whole point of switching to BFS — the limit leaves Edmonds-Karp untouched.
Verify: max flow . FF worst iterations ; EK iterations . Confirms capacity-independence of Edmonds-Karp. ✔
Example 7 — word problem: build the graph (Cell G)

- Model it. Add a super-source : edges with capacities (production limits). Middle edges each capacity . Depot edges each capacity . Sink . Why this step? Every "at most " becomes a capacity; a super-source turns "each factory produces some" into one flow value.
- Bound 1 — production: 's out-capacity .
- Bound 2 — depot forwarding: total into is .
- Bound 3 — roads (the true bottleneck): each factory reaches the depots through only units of road, but more sharply: each depot receives from factories over roads of cap , so at most enters each depot from the middle layer — total middle capacity into depots ... let's cut cleanly. Take , . Forward edges are the six roads, each cap : . Why this step? We test the middle layer as a cut — it also gives .
- Can we achieve ? Each depot must forward (its cap) and receive over three cap- roads ( ✔). Production must supply: sends ✔ (cap ), sends ... let's just balance: route each and at where possible. : . : . : ? road cap is , so sends . Total into depots . Hmm — recheck. Why this step? We must verify a cut value is actually achievable, not just an upper bound.
- Recount reachable: depot capacity forces per depot. can receive ; likewise . But each factory road is cap , and produces only , so contributes at most split as . Max middle throughput per depot but limited by production and roads. Achievable assignment: , , → gets , gets ; total . Try , → , , total . The road+production structure caps us at , not . Why this step? The naive cut gave , but a tighter cut exists. Find it.
- Tighter cut: put and . Forward edges: (cap ), plus (), () . Why this step? Cutting the low-production factory at the source edge () plus the four cap- roads of the two big factories gives — matching the achievable flow.
Verify: max flow . Achievable assignment above yields exactly into (), and the cut has capacity . Flow cut optimal. The roads-plus- bottleneck binds, not raw production. ✔
Example 8 — exam twist: node capacities & matching (Cell H)

- (8a) Node-splitting trick. Replace by two copies joined by an edge of capacity the node's limit (). All incoming edges enter , all outgoing leave . Why this step? A raw flow network only limits edges; to limit a node you force all its traffic through one internal edge.
- (8a) Solve: now (5), (3), (5). The internal edge caps everything: max flow . Min cut vs rest, capacity . Why this step? Confirms the node limit now correctly bottlenecks the flow.
- (8b) Matching-as-flow. Add super-source (cap each — each worker takes one job), each allowed pair (cap ), each (cap — each job filled once). Max flow max matching size (see Bipartite Matching). Why this step? Capacity- edges make every unit of flow a chosen pair; conservation forbids reusing a worker or job.
- (8b) Solve: is wanted by but has cap into — only one of them can use it. Best matching: , , . Size . Why this step? Route around the bottleneck: give to and to , freeing for .
Verify: (8a) max flow (the split-node edge). (8b) max matching , and the flow network achieves value with the three disjoint pairs. By König/max-flow-min-cut the min vertex cover also has size . ✔ (This is Linear Programming Duality in disguise — matching vs cover.)