Min Cut & Duality
In short: Once max flow stops growing, ask one question: which nodes can still be reached from the source using leftover residual capacity? That set is the source side of a cut, and the original pipes leaving it — the crossing edges — are exactly the ones running at full capacity. Their capacities always sum to the max flow. This is max-flow min-cut duality: the biggest amount you can push and the smallest set of pipes you'd have to sever to stop everything are the same number, proven by one reachability check on the graph the last lesson already built.

The reachable set, after the fact
The last lesson's Edmonds-Karp run on Meridian's depot network stopped because BFS couldn't reach harbour any more. Look at why, in the final residual graph: every pipe still carrying forward residual capacity, plus every reverse edge flow has opened.
The residual graph after max flow stops growing. A dashed line through the numbers would show it, but the real test is simpler — just walk from depot using whatever still has capacity.
Start at depot, the source, and walk only edges with capacity left — forward pipes that aren't full, and reverse edges flow has opened. 6 nodes, 14 edges, directed. At depot.
Why this always works
Call the reachable set S. Every pipe leaving S must be full — if it had residual capacity left, its far end would be reachable too, and it wouldn't be outside S. So the flow crossing S is at least the sum of those pipes' capacities. It can't be more, because conservation means everything that crosses S has to cross it somewhere. Those two facts pin the flow crossing S to exactly the sum of the crossing capacities — and since this is the actual max flow (BFS just confirmed no more fits), S's crossing capacity is the minimum possible over every way to split the network into a source side and a sink side. Max flow equals min cut, always, not just in this example.
In code
Nothing here is a new algorithm. It's the same residual graph, read a second time with a different question: not "can I still push more?" but "who can depot still reach?"
Quick practice
A cut that isn't the minimum
Any split of the nodes into a source side and a sink side is a cut, and its crossing capacity is always at least the max flow — min-cut just says the reachable split is the smallest one:
# the diamond network: s-a(3), s-b(2), a-b(2), a-t(2), b-t(3)
minimum_cut = 3 + 2 # {s} vs everything else
a_bigger_cut = 2 + 2 + 2 # {s, a} vs {b, t}: a-b, a-t and s-b all cross
print(minimum_cut, a_bigger_cut)Picking the wrong side
crossing_edges should return every pipe whose `from` end is inside source_side and whose `to` end is outside it. Fix the condition so it checks a in side and b not in side.
What this buys Meridian
A max-flow number alone tells dispatch "5 units an hour, full stop." The cut tells them why: axle-harbour and berth-harbour, together, are the entire bottleneck. Every other pipe in the network has slack. Widening anything that isn't on the cut buys nothing — the next lesson's dispatcher exercise leans on exactly that fact to decide where Meridian's maintenance budget should go.
| What it answers | |
|---|---|
| max flow | How much, total |
| min cut | Which pipes, exactly, are the reason it isn't more |
❓ Cross-question: "Is the min cut always unique?" No. Two different-looking cuts can both equal the max flow, if there are two genuinely separate bottlenecks of the same size. The reachable-set method always finds one valid minimum cut, not necessarily the only one.
🎯 Your turn
Write limiting_cut(pipes, source, sink). Run max flow, then find every
node still reachable from source in the final residual graph. Return
{"max_flow": total, "source_side": sorted reachable nodes, "cut_edges": sorted [from, to] pipes leaving that set, "cut_capacity": their capacity sum}:
limiting_cut([["s", "a", 3], ["a", "t", 2]], "s", "t")→{"max_flow": 2, "source_side": ["a", "s"], "cut_edges": [["a", "t"]], "cut_capacity": 2}
Hint: reuse the max-flow loop, keep the residual graph afterwards, then
walk from source over whatever still has capacity left.
Then press ▶ Run, tap the Live App try chips to call it with different inputs, and hit ✓ Check. Green = this piece of Meridian's dispatcher is built. ✅
