Network Flow: Max-Flow Min-Cut

This deck covers flow networks and the two rules a valid flow obeys, residual graphs and why augmenting paths need back edges, the Ford-Fulkerson and Edmonds-Karp algorithms, the max-flow min-cut theorem, and the reduction from bipartite matching. It targets four real misconceptions: exceeding an edge's capacity, forgetting the residual back edges, confusing the value of the max flow with the capacity of the min cut, and assuming that a single greedy highest-capacity path finishes the job. Every trace was verified by hand.

Subject: CS3000 Algorithms · 130 slides · symbolic lesson

Open the interactive version of this deck · Homework for this lesson

What this lesson covers

The lesson, slide by slide

1. Network Flow: Max-Flow Min-Cut

Title

CS3000 Algorithms

How much can flow through a network, and how do you prove you've found the most?

2. What you will be able to do

Objectives

By the end of this lesson you can:

  1. Explain what a flow network is, and check whether a flow obeys its two rules.
  2. Build a residual graph, explain why back edges exist, and use one to fix an earlier choice.
  1. Trace the Ford-Fulkerson method and Edmonds-Karp by hand to find a maximum flow.
  2. State the max-flow min-cut theorem in plain language and verify it on a network.
  1. Model a bipartite matching problem as a flow network and read off a maximum matching.
  2. Explain, in one line, why flow sits at the efficient end of the algorithms you will meet this term.

3. What survived from Minimum Spanning Trees: Prim & Kruskal?

Warm-up

Discussion prompt

Before we open Network Flow: Max-Flow Min-Cut: without looking back, what was the main idea of Minimum Spanning Trees: Prim & Kruskal, and what could you do by the end of it that you could not do before?

Hint: One sentence for the idea, one for the skill. If the second one is blank, that is the part to revisit.

Answer:

That deck explains what a minimum spanning tree is, then gives the cut property and the cycle property that make greedy MST algorithms provably correct. It includes full hand-traced runs of Prim's and Kruskal's algorithms, the latter with union-find, along with their running times. It targets the misconceptions that an MST is always unique, that it is the same thing as a shortest-path tree, that Kruskal never needs a cycle check, and that union-find stores weights or paths rather than connectivity alone.

4. Toolkit check-in: name them before you look

Concept

Before any new material: cover the screen.

You have named 15 reusable moves so far. Say as many as you can out loud, by number, from memory.

Do not advance until you have actually tried. Getting four of eight is information; skipping the exercise is not.

Here they are. Score yourself.

Today adds one move to this list. Everything else you will need is already above.

The question that starts every proof from here on is not how do I begin. It is which of these applies here?

5. Break it if you can: Toolkit check-in: name them before you look

Counterexample

Discussion prompt

You have named 15 reusable moves so far. Say as many as you can out loud, by number, from memory.

That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.

Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.

Answer:

Do not advance until you have actually tried. Getting four of eight is information; skipping the exercise is not.

6. Flow Networks: The Basics

Section

Section 1

7. Picture it first: What a flow network is

Picture it

Figure (svg): A flow network with four nodes s, a, b, t. Edges go from s to a, s to b, a to b, a to t, and b to t, each labeled capacity 1.

Discussion prompt

Read the picture before the words. What is this showing, and what is the one thing it is built to make obvious? Commit to an answer, then read on.

Hint: Name the parts, then say what changes between them — and if nothing changes, say what is being held still.

Answer:

A flow network is a directed graph built for one job: moving something from a single starting point to a single ending point.

8. What a flow network is

Concept

A flow network is a directed graph built for one job: moving something from a single starting point to a single ending point.

source — The one node everything starts from, usually named s. Nothing flows into the source in a well-formed network.

sink — The one node everything ends up at, usually named t. Nothing flows out of the sink.

Every other node is an internal node: things pass through it, but nothing is created or destroyed there.

capacity — Every directed edge carries a capacity, the maximum amount that edge can carry. Write the capacity of the edge from u to v as c(u,v).

Figure (svg): A flow network with four nodes s, a, b, t. Edges go from s to a, s to b, a to b, a to t, and b to t, each labeled capacity 1.

This four-node network, s, a, b, t, will run through the whole lesson. Every edge here happens to have capacity 1, which keeps the arithmetic simple while the ideas stay real.

9. Take the definitions apart: source vs sink

Definition probe

Sort into buckets

Every line below is part of the definition of source or of sink — one or the other, never both. Put each where it belongs.

source
The one node everything starts from, usually named s.; Nothing flows into the source in a well-formed network.
sink
The one node everything ends up at, usually named t.; Nothing flows out of the sink.
b1
The one node everything starts from, usually named s. Nothing flows into the source in a well-formed network.
b2
The one node everything ends up at, usually named t. Nothing flows out of the sink.

10. A flow network is a weighted digraph

Picture it

Animation

Shows: A flow network is a weighted digraph — a rendered Manim animation.

Rendered with Manim.

Takeaway: Weights are capacities — a ceiling on each pipe, not a cost.

11. Capacities only run one way

Concept

An edge from s to a with capacity 1 says nothing about a direction from a back to s. If that reverse edge is not drawn in the network, its capacity is 0.

\[ c(s,a) = 1 \quad \text{but} \quad c(a,s) = 0 \ \text{(no such edge drawn)} \]

Keep this in mind. Later, the algorithm will invent a way to move flow backward along an edge, but that is a separate bookkeeping trick, not a claim that the original network secretly had a reverse edge with real capacity.

12. By analogy: Capacities only run one way

Analogy

Discussion prompt

Explain Capacities only run one way by analogy to something with no CS3000 Algorithms in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.

Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.

Answer:

An edge from s to a with capacity 1 says nothing about a direction from a back to s. If that reverse edge is not drawn in the network, its capacity is 0.

13. Pipes carrying water

Intuition

Picture the network as pipes. Each directed edge is a pipe with a maximum flow rate, the capacity. Water pours in at the source and must come out at the sink.

A pipe can be running below its maximum, right at its maximum, or empty. What a pipe can never do is carry more water than its capacity allows, and water can never appear or vanish inside a pipe junction.

14. Teach it back: Pipes carrying water

Explain it

Discussion prompt

Explain Pipes carrying water to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.

Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.

Answer:

Picture the network as pipes. Each directed edge is a pipe with a maximum flow rate, the capacity. Water pours in at the source and must come out at the sink.

15. Rule one: never exceed capacity

Concept

A flow assigns a number to every edge, how much is currently moving through it. The first rule any valid flow must obey is the capacity constraint.

\[ 0 \le f(u,v) \le c(u,v) \quad \text{for every edge } (u,v) \]

The flow on an edge can be zero, it can equal the capacity exactly, or anything in between. It can never go negative and it can never go over.

16. Rule two: flow in equals flow out

Concept

The second rule is flow conservation: at every internal node (not the source, not the sink), the total flow arriving must exactly equal the total flow leaving.

flow conservation — For every internal node v, the sum of flow on edges coming in equals the sum of flow on edges going out. Nothing is stored or created at an internal node.

\[ \sum_{u} f(u,v) \;=\; \sum_{w} f(v,w) \quad \text{for every internal node } v \]

Only the source and the sink are allowed to have an imbalance. Everywhere else, whatever comes in during one instant must leave during that same instant.

17. Picture it first: Verify a candidate flow is valid

Picture it

Figure (svg): The s, a, b, t network with flow labeled on each edge: s to a carries 1 of 1, a to t carries 1 of 1, s to b carries 1 of 1, b to t carries 1 of 1, and a to b carries 0 of 1.

Discussion prompt

Read the picture before the words. What is this showing, and what is the one thing it is built to make obvious? Commit to an answer, then read on.

Hint: Name the parts, then say what changes between them — and if nothing changes, say what is being held still.

Answer:

On the s, a, b, t network, check whether this assignment is a valid flow: 1 unit on s to a, 1 unit on a to t, 1 unit on s to b, 1 unit on b to t, and 0 on a to b.

18. Verify a candidate flow is valid

Worked example

On the s, a, b, t network, check whether this assignment is a valid flow: 1 unit on s to a, 1 unit on a to t, 1 unit on s to b, 1 unit on b to t, and 0 on a to b.

Figure (svg): The s, a, b, t network with flow labeled on each edge: s to a carries 1 of 1, a to t carries 1 of 1, s to b carries 1 of 1, b to t carries 1 of 1, and a to b carries 0 of 1.

Check the capacity constraint on every edge

Why: Every listed flow value is either 0 or 1, and every capacity is 1. No edge carries more than it can hold, so rule one holds everywhere.

edgeflowcapacitywithin capacity
s to a11yes
s to b11yes
a to b01yes
a to t11yes
b to t11yes

Check conservation at node a

Why: Flow into a is only from s to a, which is 1. Flow out of a is a to b (0) plus a to t (1), which totals 1. In equals out.

\[ \text{in}(a) = 1, \quad \text{out}(a) = 0 + 1 = 1 \]

Check conservation at node b

Why: Flow into b is s to b (1) plus a to b (0), totaling 1. Flow out of b is b to t, which is 1. In equals out again.

\[ \text{in}(b) = 1 + 0 = 1, \quad \text{out}(b) = 1 \]

Verify both rules hold at every internal node and edge

Why: Rule one held on all five edges, and rule two held at both internal nodes a and b. Nothing was checked at s or t because conservation is never required there. This is a valid flow.

19. What stays fixed: Verify a candidate flow is valid

Invariant

Step through it

Step through Verify a candidate flow is valid one row at a time. One of these columns never changes — find it, and say why it cannot.

  1. Step 1: edge is s to a
  2. Step 2: edge is s to b
  3. Step 3: edge is a to b
  4. Step 4: edge is a to t
  5. Step 5: edge is b to t

20. What has to happen first: Conservation with two incoming edges

Ranking

Put in order

Put the moves of Conservation with two incoming edges into the order they have to happen.

  1. Add up everything arriving at c
  2. Compare to what leaves c
  3. Verify the node balances

Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. Two separate edges deliver flow into c.

21. Conservation with two incoming edges

Worked example

Conservation has to balance every edge touching a node, not just one pair. Suppose node c has two edges coming in and a single edge going out.

edgedirectionflow
x to cin2
y to cin1
c to zout3

Add up everything arriving at c

Why: Two separate edges deliver flow into c. Conservation cares about the total arriving, not any single edge.

\[ \text{in}(c) = f(x,c) + f(y,c) = 2 + 1 = 3 \]

Compare to what leaves c

Why: Only one edge leaves c, carrying 3 units.

\[ \text{out}(c) = f(c,z) = 3 \]

Verify the node balances

Why: 3 arriving equals 3 leaving, so conservation holds at c even though the in-degree and out-degree are different. Conservation is about totals, not about matching the number of edges.

22. Conservation with two incoming edges — line by line

Picture it

Animation

Shows: Each line of the worked example "Conservation with two incoming edges", appearing one at a time.

The same working the example does, in the order a tutor would write it.

Takeaway: 3 arriving equals 3 leaving, so conservation holds at c even though the in-degree and out-degree are different. Conservation is about totals, not about matching the number of edges.

23. Something is wrong here: sending more than the pipe can carry

Anomaly

Predict first

A student writes this, and it looks reasonable:

A student wants more flow through the network fast, so they push 2 units across the edge from s to a, whose capacity is only 1.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: This directly breaks the capacity constraint: 2 is greater than the capacity 1.

An edge's capacity is a hard ceiling, not a suggestion. If more needs to move from s to a than one edge allows, it has to go by some other route entirely, using a different edge.

Why: This directly breaks the capacity constraint: 2 is greater than the capacity 1. This is not a flow with a strange property, it is not a flow at all, and every conclusion drawn from it is meaningless.

24. Trap: sending more than the pipe can carry

Trap

The trap

A student wants more flow through the network fast, so they push 2 units across the edge from s to a, whose capacity is only 1.

\[ c(s,a) = 1 \]

Assign f(s,a) = 2 anyway

Why: This directly breaks the capacity constraint: 2 is greater than the capacity 1. This is not a flow with a strange property, it is not a flow at all, and every conclusion drawn from it is meaningless.

\[ f(s,a) = 2 \ \not\le\ c(s,a) = 1 \]

The fix

An edge's capacity is a hard ceiling, not a suggestion. If more needs to move from s to a than one edge allows, it has to go by some other route entirely, using a different edge.

\[ c(s,a) = 1 \]

Respect the ceiling: f(s,a) at most 1

Why: Any valid assignment keeps this edge at 0 or 1. If the network needs to move more total flow from s, it must also use the separate edge from s to b, which has its own, independent capacity.

\[ f(s,a) \le 1, \quad \text{extra flow must use a different edge, e.g. } f(s,b) \le 1 \]

25. Decode the notation: Trap: sending more than the pipe can carry

Notation

Annotate

From Trap: sending more than the pipe can carry — read this one piece at a time. What is each part doing?

On: \( f(s,a) = 2 \ \not\le\ c(s,a) = 1 \)

  • This directly breaks the capacity constraint: 2 is greater than the capacity 1. This is not a flow with a strange property, it is not a flow at all, and every conclusion drawn from it is meaningless.
  • Any valid assignment keeps this edge at 0 or 1. If the network needs to move more total flow from s, it must also use the separate edge from s to b, which has its own, independent capacity.

26. The value of a flow

Concept

A flow's value is the total amount actually making it from source to sink, the number that matters. Because of conservation, you can measure it in either of two equal ways.

value of a flow — The net amount of flow leaving the source, written |f|. It equals the net amount arriving at the sink, because nothing is created or lost along the way.

\[ |f| \;=\; \sum_{v} f(s,v) \;=\; \sum_{v} f(v,t) \]

This equality is not a coincidence to verify by luck, it follows directly from conservation holding at every node strictly between s and t.

27. Term to definition: Network Flow: Max-Flow Min-Cut

Matching

Match the pairs

Match each term to the definition this lesson gave it — not the one you would guess from the word.

  • t1. source
  • t2. sink
  • t3. capacity
  • t4. flow conservation
  • t5. value of a flow
  • d1. The one node everything starts from, usually named s. Nothing flows into the source in a well-formed network.
  • d2. The one node everything ends up at, usually named t. Nothing flows out of the sink.
  • d3. Every directed edge carries a capacity, the maximum amount that edge can carry. Write the capacity of the edge from u to v as c(u,v).
  • d4. For every internal node v, the sum of flow on edges coming in equals the sum of flow on edges going out. Nothing is stored or created at an internal node.
  • d5. The net amount of flow leaving the source, written |f|. It equals the net amount arriving at the sink, because nothing is created or lost along the way.

Why: These are the working definitions of source, sink, capacity, flow conservation, value of a flow as Network Flow: Max-Flow Min-Cut uses them. Pairing them correctly is the test of whether you could state each one with the slide switched off.

28. Conservation at every interior node

Picture it

Animation

Shows: Conservation at every interior node — a rendered Manim animation.

Rendered with Manim.

Takeaway: The constraint that makes flow a flow rather than an arbitrary labelling.

29. Plan first: Compute the value of a flow

Step zero

Discussion prompt

Compute the value of a flow — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.

Hint: It starts with: Sum the flow leaving the source

Answer:

  1. Sum the flow leaving the source
  2. Sum the flow arriving at the sink
  3. Verify both totals agree

30. Compute the value of a flow

Worked example

Use the same valid flow as before: 1 on s to a, 1 on s to b, 0 on a to b, 1 on a to t, 1 on b to t. Find the value two ways.

Sum the flow leaving the source

Why: Only two edges leave s: s to a and s to b, carrying 1 unit each.

\[ \sum_v f(s,v) = f(s,a) + f(s,b) = 1 + 1 = 2 \]

Sum the flow arriving at the sink

Why: Only two edges enter t: a to t and b to t, carrying 1 unit each.

\[ \sum_v f(v,t) = f(a,t) + f(b,t) = 1 + 1 = 2 \]

Verify both totals agree

Why: Both computations give 2, exactly as conservation guarantees. The value of this flow is 2, whichever side you measure from.

\[ |f| = 2 \]

31. Compute the value of a flow — line by line

Picture it

Animation

Shows: Each line of the worked example "Compute the value of a flow", appearing one at a time.

The same working the example does, in the order a tutor would write it.

Takeaway: Both computations give 2, exactly as conservation guarantees. The value of this flow is 2, whichever side you measure from.

32. Residual Graphs & Augmenting Paths

Section

Section 2

33. Residual capacity: how much more can go through

Concept

Given a current flow, the residual capacity of an edge is how much additional flow could still be pushed along it right now.

residual capacity — For an edge (u,v) carrying flow f(u,v) out of a total capacity c(u,v), the residual capacity is what remains unused: capacity minus current flow.

\[ c_f(u,v) \;=\; c(u,v) - f(u,v) \]

If an edge is carrying 1 out of a capacity of 1, its residual capacity is 0: completely full, nothing more can be pushed along it in the forward direction.

34. Why we need an undo button

Intuition

Imagine you send flow along a path that looked promising, but it turns out to block off a better overall arrangement. Without some way to reroute, the algorithm would be stuck with its first choice forever.

The fix is to let the algorithm partially cancel an earlier decision, as if flowing backward along an edge that already carries flow. That is exactly what a back edge in the residual graph represents: an offer to undo, not a real physical pipe running the other way.

35. The residual graph, formally

Concept

The residual graph for a given flow has, for every original edge, up to two residual edges: a forward one and a backward one.

residual graph — A graph built from the current flow: a forward residual edge (u,v) whenever capacity remains, and a backward residual edge (v,u) whenever there is flow on (u,v) to undo.

\[ c_f(u,v) = c(u,v) - f(u,v) \qquad \text{(forward, leftover capacity)} \]

\[ c_f(v,u) = f(u,v) \qquad \text{(backward, the flow available to undo)} \]

Traversing a forward residual edge sends new flow along a real edge. Traversing a backward residual edge cancels flow that was previously sent the other way. Both are legal moves in the residual graph.

36. Plan first: Compute every residual capacity in the network

Step zero

Discussion prompt

Compute every residual capacity in the network — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.

Hint: It starts with: Compute the forward residuals

Answer:

  1. Compute the forward residuals
  2. Compute the backward residuals
  3. Verify: every residual capacity is non-negative and accounted for

37. Compute every residual capacity in the network

Worked example

Take the flow from Section 1: 1 on s to a, 1 on s to b, 0 on a to b, 1 on a to t, 1 on b to t. Find the residual capacity of every possible edge, forward and backward.

Compute the forward residuals

Why: Forward residual capacity is capacity minus flow, for each of the five original edges.

edgecapacityflowforward residual
s to a110
s to b110
a to b101
a to t110
b to t110

Compute the backward residuals

Why: Backward residual capacity equals the flow currently on that edge, since that is exactly how much could be undone.

back edgeequals flow onbackward residual
a to ss to a1
b to ss to b1
b to aa to b0
t to aa to t1
t to bb to t1

Verify: every residual capacity is non-negative and accounted for

Why: Every forward residual is capacity minus flow (never negative, since flow never exceeds capacity), and every backward residual equals a flow value (also never negative). All ten numbers above are consistent with the flow they came from.

38. Build the residual graph after one greedy step

Worked example

Start from zero flow. Suppose an algorithm greedily sends flow along the first path it notices, s to a to b to t, without any particular strategy.

Figure (svg): The s, a, b, t network with the path s to a, a to b, b to t highlighted in green each carrying flow 1 of capacity 1, while s to b and a to t remain at flow 0 of capacity 1.

Find the bottleneck of the chosen path

Why: The path s to a to b to t crosses three edges with capacities 1, 1, and 1. The bottleneck is the smallest residual capacity along the path, here 1.

\[ \text{bottleneck} = \min(c_f(s,a), c_f(a,b), c_f(b,t)) = \min(1,1,1) = 1 \]

Send 1 unit along the path

Why: Every edge on the path gets its flow increased by the bottleneck amount, 1. This saturates all three edges at once, since they all had capacity exactly 1.

\[ f(s,a)=1,\ f(a,b)=1,\ f(b,t)=1,\ f(s,b)=0,\ f(a,t)=0 \]

Build the resulting residual graph

Why: The three saturated edges now have forward residual 0, but each gains a backward residual edge equal to its flow. The two untouched edges keep their full forward residual capacity.

Figure (svg): Residual graph after the greedy step: forward edges s to b and a to t remain with residual capacity 1, while three dashed amber back edges appear, a to s, b to a, and t to b, each with residual capacity 1.

Verify the residual graph matches the table computed earlier

Why: Forward residuals of 0 on s to a, a to b, b to t, and 1 on s to b, a to t; backward residuals of 1 on a to s, b to a, t to b. This matches the ten values computed edge by edge in the previous slide, so the residual graph is built correctly.

39. Work backwards from the answer: Build the residual graph after one greedy…

Reverse engineer

Discussion prompt

Work backwards. The example finished here:

Verify the residual graph matches the table computed earlier

What was it asked to do, and what must it have been given? Reconstruct the problem from its answer.

Hint: Every quantity in the result had to enter somewhere. Account for each one.

Answer:

Start from zero flow. Suppose an algorithm greedily sends flow along the first path it notices, s to a to b to t, without any particular strategy.

40. An augmenting path can use forward or back edges

Concept

An augmenting path is any path from source to sink in the current residual graph, where every edge on it has positive residual capacity. Forward and backward residual edges are both fair game.

augmenting path — A path from s to t through the residual graph along which every edge has residual capacity greater than 0. Sending flow along it strictly increases the value of the flow.

This is the whole point of the residual graph: it lets the search for more flow travel along a real leftover pipe, or backward to partially cancel a pipe that is already carrying flow, whichever leads somewhere useful.

41. Process: greedy flow without an undo button

Intuition

Watch me not know the answer. This is what the first two minutes actually look like.

Push flow greedily along whatever source-to-sink path you find, and never revisit a decision.

Try it: find any path with spare capacity and saturate it

Why: It is the obvious algorithm, it always terminates, and on most small networks it gives the right answer.

One bad first choice locks in a suboptimal answer

Why: Route flow through a middle edge that two different paths needed, and the second path is now blocked. No forward path remains, yet the flow is not maximum — and no amount of further forward searching will fix it.

Dead end. Not a mistake — a move that was worth trying and did not pay off. This happens in most proofs.

Back up. Allow a step to cancel an earlier one

Why: Give every used edge a residual back edge equal to the flow on it. Sending flow along that back edge means retract this much of the earlier decision, and now the search can repair its own mistakes.

The residual graph is not bookkeeping. It is the undo button that makes greedy correct. This is a general pattern: greedy plus a principled way to revoke a choice is often exactly enough.

The expert does not see the whole path in advance. The expert tries something, reads the result, and adjusts. That is the skill.

42. What has to happen first: Find an augmenting path that uses a back edge

Ranking

Put in order

Put the moves of Find an augmenting path that uses a back edge into the order they have to happen.

  1. Try s to b, using the untouched forward edge
  2. From b, cross the back edge to a
  3. From a, take the untouched forward edge to t
  4. Augment along this path
  5. Verify the new flow is valid and larger

Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. The edge s to b was never used by the greedy step, so its forward residual capacity is still 1.

43. Find an augmenting path that uses a back edge

Worked example

Continue from the residual graph just built, after the greedy step sent 1 unit along s to a to b to t. Search for another augmenting path from s to t.

Try s to b, using the untouched forward edge

Why: The edge s to b was never used by the greedy step, so its forward residual capacity is still 1. This is a legal first hop.

\[ c_f(s,b) = 1 \]

From b, cross the back edge to a

Why: The edge a to b currently carries 1 unit of flow, so the backward residual edge b to a has residual capacity equal to that flow, 1. Traversing it will cancel 1 unit of flow on a to b.

\[ c_f(b,a) = f(a,b) = 1 \]

From a, take the untouched forward edge to t

Why: The edge a to t was never used, so its forward residual capacity is still 1. The path s to b to a to t is complete, with bottleneck 1.

\[ \text{bottleneck} = \min(1,1,1) = 1 \]

Augment along this path

Why: Increase flow by 1 on the two forward edges used, s to b and a to t. Decrease flow by 1 on the edge whose back edge was used, a to b, since crossing a back edge cancels flow on the original edge.

\[ f(s,b): 0 \to 1, \qquad f(a,t): 0 \to 1, \qquad f(a,b): 1 \to 0 \]

Verify the new flow is valid and larger

Why: The resulting flow is f(s,a)=1, f(s,b)=1, f(a,b)=0, f(a,t)=1, f(b,t)=1: exactly the valid flow verified in Section 1, with value 2. Conservation still holds at a (in 1, out 1) and at b (in 1, out 1), and the value grew from 1 to 2. The back edge did not add a new physical pipe, it rerouted flow that the greedy step had trapped.

44. Find a path with spare capacity, then push

Picture it

Animation

Shows: Find a path with spare capacity, then push — a rendered Manim animation.

Rendered with Manim.

Takeaway: The bottleneck edge is what limits the whole path.

45. Something is wrong here: forgetting the back edges

Anomaly

Predict first

A student writes this, and it looks reasonable:

After the greedy step sends 1 unit along s to a to b to t, a student builds a residual graph using only forward edges, the leftover capacity, and ignores the possibility of undoing flow.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: Without back edges, s to b leads to b, and there is no forward edge from b to a or b to t left, so the search dead-ends.

The residual graph always includes backward edges, one for every edge currently carrying flow, with residual capacity equal to that flow.

Why: Without back edges, s to b leads to b, and there is no forward edge from b to a or b to t left, so the search dead-ends. The student reports the maximum flow as 1, the value found after the very first path.

46. Trap: forgetting the back edges

Trap

The trap

After the greedy step sends 1 unit along s to a to b to t, a student builds a residual graph using only forward edges, the leftover capacity, and ignores the possibility of undoing flow.

In that forward-only picture, the only edges with residual capacity are s to b and a to t, and they do not connect to each other (no edge from b to a exists going forward).

Conclude no augmenting path exists and stop

Why: Without back edges, s to b leads to b, and there is no forward edge from b to a or b to t left, so the search dead-ends. The student reports the maximum flow as 1, the value found after the very first path.

\[ \text{reported (wrong) max flow} = 1 \]

The fix

The residual graph always includes backward edges, one for every edge currently carrying flow, with residual capacity equal to that flow.

Adding the back edge b to a (residual capacity 1, since a to b carries 1 unit of flow) reopens the search: s to b to a to t is a full augmenting path.

Augment along s to b to a to t and find the true maximum

Why: This path was only visible because the back edge b to a exists. Augmenting along it raises the value from 1 to 2, and no augmenting path remains afterward, since s to a and s to b become saturated with nothing left to reach t.

\[ \text{true max flow} = 2 \]

47. Ford-Fulkerson & Edmonds-Karp

Section

Section 3

48. The Ford-Fulkerson method

Concept

The Ford-Fulkerson method finds a maximum flow with one repeated move: find any augmenting path in the residual graph, push as much flow as the bottleneck allows, rebuild the residual graph, and repeat.

Ford-Fulkerson method — Start with zero flow. While an augmenting path from s to t exists in the residual graph, augment along it. Stop when no augmenting path remains.

It is called a method rather than a single algorithm because it does not say which augmenting path to pick when several are available, only that you must keep going until none exist.

49. Ford-Fulkerson in pseudocode

Concept

Find any path from source to sink with room left on it, push as much as its tightest edge allows, and repeat until no such path exists.

FORD-FULKERSON(G, s, t)
  for each edge (u, v)
    f(u, v) = 0
  while an augmenting path P exists in G_f
    b = min residual capacity along P
    for each edge (u, v) in P
      f(u, v) = f(u, v) + b
      f(v, u) = f(v, u) - b
  return f

Line 8 is the one that looks wrong and is not. Sending flow forward creates the option of sending it back later, and that back edge is what lets a later path undo an earlier bad routing decision. Without it the method would get stuck at a non-maximum flow.

50. Reading FORD-FULKERSON line by line

Notation

Every line of FORD-FULKERSON says one thing. Read the line, then read what it does — not the other way round.

Annotate

  • Any path with room left, in the residual graph — not the original one. Which path you pick changes the speed, never the final answer.
  • The bottleneck. A chain is as strong as its weakest link, so the tightest edge on the path decides how much can be pushed.
  • Push the bottleneck amount along every edge of the path, so conservation still holds at every vertex in the middle.
  • The back edge. This is not real flow — it is a recorded permission to undo, and it is what makes the method correct rather than merely greedy.
  • The loop ends when no path remains. At that moment the vertices still reachable from s form one side of a minimum cut.
  • The value of the returned flow equals the capacity of that cut. That equality is the max-flow min-cut theorem.

51. Step FORD-FULKERSON yourself

Invariant

The flow is legal at every step: no edge exceeds its capacity, and everything into a middle vertex comes back out. Only the total ever rises.

Step through it

At each path, find the bottleneck edge yourself before stepping.

  1. Line 3: no flow anywhere yet
  2. Line 4: a path exists: s to a to t
  3. Line 5: the tightest edge on it allows 3
  4. Line 7: push 3 along the whole path
  5. Line 4: another path: s to b to t
  6. Line 5: this one bottlenecks at 2
  7. Line 7: total is now 5
  8. Line 8: the back edge records the right to reroute
  9. Line 4: no path with room left remains
  10. Line 9: 5 is the max flow, and some cut has capacity 5

52. Push along a path, keep the right to take it back

Picture it

Animation

Shows: FORD-FULKERSON executing: the current line of pseudocode is highlighted while the data it touches changes.

Rendered with Manim.

Takeaway: Push the bottleneck amount along any path with room left; the back edges are what let a later path undo an earlier choice.

53. Keep going until the well runs dry

Intuition

Each augmenting path is one more trip that carries some water from source to sink. As long as some route, forward or backward through the residual graph, can still carry something, there is more flow to find.

The method only declares victory when every route from s to t in the residual graph is completely blocked, not before. Stopping early just because the most recent path looked big is exactly the mistake to avoid.

54. Picture it first: Ford-Fulkerson, iteration 1: send the big path

Picture it

Figure (svg): A network with s to a capacity 10, a to t capacity 10, s to b capacity 1, and b to t capacity 1. There is no edge between a and b.

Discussion prompt

Read the picture before the words. What is this showing, and what is the one thing it is built to make obvious? Commit to an answer, then read on.

Hint: Name the parts, then say what changes between them — and if nothing changes, say what is being held still.

Answer:

Consider a different network: s to a with capacity 10, a to t with capacity 10, s to b with capacity 1, and b to t with capacity 1. There is no edge between a and b.

55. Ford-Fulkerson, iteration 1: send the big path

Worked example

Consider a different network: s to a with capacity 10, a to t with capacity 10, s to b with capacity 1, and b to t with capacity 1. There is no edge between a and b.

Figure (svg): A network with s to a capacity 10, a to t capacity 10, s to b capacity 1, and b to t capacity 1. There is no edge between a and b.

Find an augmenting path and its bottleneck

Why: Starting from zero flow, the path s to a to t is available, with residual capacities 10 and 10 on its two edges. The bottleneck is the smaller of the two, but here they are equal.

\[ \text{bottleneck} = \min(c_f(s,a), c_f(a,t)) = \min(10,10) = 10 \]

Augment by 10 along s to a to t

Why: Both edges on this path get their flow raised by 10, saturating them completely.

\[ f(s,a) = 10, \quad f(a,t) = 10, \quad \text{value so far} = 10 \]

Check whether this is already the final answer

Why: The path used was the biggest-looking one in the network, but the method's stopping rule only cares whether an augmenting path still exists, not how large the last one felt. That check comes next, on the residual graph.

56. Draw the shape of it: Ford-Fulkerson, iteration 1: send the big…

Blank canvas

Draw it

Draw what Ford-Fulkerson, iteration 1: send the big path just did — the shape of it, not the line-by-line working. One picture, labels only where you need them. Then check it against the steps: anything you could not draw is a step you followed rather than understood.

57. Plan first: Ford-Fulkerson, iteration 2: find what's left

Step zero

Discussion prompt

Ford-Fulkerson, iteration 2: find what's left — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.

Hint: It starts with: Check the residual graph for another augmenting path

Answer:

  1. Check the residual graph for another augmenting path
  2. Augment by 1 along s to b to t
  3. Confirm no augmenting path remains
  4. Verify the final value against the network's own limit

58. Ford-Fulkerson, iteration 2: find what's left

Worked example

After sending 10 units along s to a to t, both of those edges are saturated: their forward residual capacity is 0. But the method is not finished, since s to t routes might still exist elsewhere.

Check the residual graph for another augmenting path

Why: The edges s to b and b to t were never touched, so their forward residual capacity is still their full capacity, 1 each. The path s to b to t is available.

\[ c_f(s,b) = 1, \quad c_f(b,t) = 1 \]

Augment by 1 along s to b to t

Why: The bottleneck of this path is 1, so both edges are raised by 1, saturating them too.

\[ f(s,b) = 1, \quad f(b,t) = 1, \quad \text{new total value} = 10 + 1 = 11 \]

Confirm no augmenting path remains

Why: Every edge leaving s, both s to a and s to b, is now saturated with forward residual 0. Since s has no other way out in the residual graph, no augmenting path from s to t can exist. The method halts.

Verify the final value against the network's own limit

Why: The total capacity leaving s is 10 plus 1, which is 11. The flow found, 11, exactly matches that ceiling, so no larger flow was possible in the first place.

\[ \text{max flow} = 11 = c(s,a) + c(s,b) \]

59. Ford-Fulkerson, iteration 2: find what's left — line by line

Picture it

Animation

Shows: Each line of the worked example "Ford-Fulkerson, iteration 2: find what's left", appearing one at a time.

The same working the example does, in the order a tutor would write it.

Takeaway: The edges s to b and b to t were never touched, so their forward residual capacity is still their full capacity, 1 each. The path s to b to t is available.

60. What feels wrong about stopping when no forward path remains?

Intuition

What feels wrong about this?

You push flow along the fattest path you can find, then look again and no forward path from source to sink survives.

\[ \text{no forward path} \;\Rightarrow\; \text{done?} \]

_Plain English only. No notation, no algebra. Just say what bothers you._

The feeling: you committed to a route early and now you are stuck with it, even though a different early choice might have left more room.

That feeling is the proof. It is not a substitute for the proof — it is the thing the proof writes down.

That is exactly what residual back edges fix. They let a later step undo part of an earlier commitment, which is why greedy without an undo button is not enough here — and why the stopping condition is about the residual graph, not the original one.

61. Something is wrong here: stopping after the fattest pipe

Anomaly

Predict first

A student writes this, and it looks reasonable:

A student sends 10 units along s to a to t, the obviously largest-looking path in the network, and stops there, assuming the biggest pipe must be the whole story.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: This misses the entirely separate route through b.

Picking a big path first is a fine start, but the method's stopping condition is about the residual graph, not about how impressive the last path felt.

Why: This misses the entirely separate route through b. The edge s to b (capacity 1) and b to t (capacity 1) were never touched, so 1 more unit of flow is sitting right there, unused. Ford-Fulkerson is not finished until no augmenting path remains, no matter how large the first one looked.

62. Trap: stopping after the fattest pipe

Trap

The trap

A student sends 10 units along s to a to t, the obviously largest-looking path in the network, and stops there, assuming the biggest pipe must be the whole story.

\[ \text{reported (wrong) max flow} = 10 \]

Declare victory after one big path

Why: This misses the entirely separate route through b. The edge s to b (capacity 1) and b to t (capacity 1) were never touched, so 1 more unit of flow is sitting right there, unused. Ford-Fulkerson is not finished until no augmenting path remains, no matter how large the first one looked.

The fix

Picking a big path first is a fine start, but the method's stopping condition is about the residual graph, not about how impressive the last path felt.

\[ \text{stop only when no augmenting path remains} \]

Keep searching after every augmentation

Why: After the 10-unit path, check the residual graph again: s to b to t is still open, with bottleneck 1. Augmenting there brings the true total to 11. Only now, with both edges out of s saturated, is the method actually done.

\[ \text{true max flow} = 11 \]

63. Say it in words: Trap: stopping after the fattest pipe

Translation

\( \text{stop only when no augmenting path remains} \)

Draw it

Translate both ways. First write the expression above as a sentence with no symbols in it at all. Then cover it, and write your sentence back as notation. If the two versions disagree, the disagreement is the thing to fix.

64. Why Ford-Fulkerson must eventually stop

Concept

For integer capacities, every augmenting path has a bottleneck of at least 1, since residual capacities are whole numbers whenever capacities and flow start as whole numbers.

\[ \text{each augmentation raises } |f| \text{ by at least } 1 \]

Since the flow's value can never exceed the total capacity leaving the source, a finite ceiling, the method cannot augment forever. It must halt after finitely many steps, having found some maximum flow.

65. Edmonds-Karp: always augment along a shortest path

Concept

The Ford-Fulkerson method leaves open which augmenting path to choose. Edmonds-Karp fixes a specific rule: always pick a shortest augmenting path, the one with the fewest edges, found by a breadth-first search of the residual graph.

Edmonds-Karp — The Ford-Fulkerson method where every augmenting path is chosen to be a shortest path, in number of edges, using breadth-first search on the residual graph.

It still uses the exact same residual graph machinery, forward and backward edges included. The only change is the search strategy used to pick which augmenting path to take next.

66. Why shortest-first stays fast

Intuition

An arbitrary choice of augmenting path can, on some networks, force an enormous number of tiny augmentations before finishing, one painstaking unit at a time.

Always taking a shortest path prevents that slow crawl: it can be proven that the shortest-path distance from s to t never decreases as augmentations happen, which bounds the total number of iterations by a polynomial in the size of the network.

67. Plan first: An Edmonds-Karp trace

Step zero

Discussion prompt

An Edmonds-Karp trace — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.

Hint: It starts with: Find the shortest augmenting paths available

Answer:

  1. Find the shortest augmenting paths available
  2. Augment along s to a to t
  3. Search again and augment along s to b to t
  4. Verify no augmenting path remains

68. An Edmonds-Karp trace

Worked example

Return to the s, a, b, t network with all five capacities equal to 1. Run Edmonds-Karp from zero flow, always taking a shortest augmenting path.

Find the shortest augmenting paths available

Why: From s to t, the paths s to a to t and s to b to t both have length 2 edges, while s to a to b to t has length 3. A breadth-first search finds a length-2 path first.

\[ \text{length}(s{\to}a{\to}t) = 2, \quad \text{length}(s{\to}b{\to}t) = 2, \quad \text{length}(s{\to}a{\to}b{\to}t) = 3 \]

Augment along s to a to t

Why: Bottleneck is 1. This saturates s to a and a to t.

\[ f(s,a) = 1, \quad f(a,t) = 1, \quad \text{value} = 1 \]

Search again and augment along s to b to t

Why: The remaining shortest augmenting path is s to b to t, length 2, bottleneck 1. This saturates s to b and b to t.

\[ f(s,b) = 1, \quad f(b,t) = 1, \quad \text{value} = 2 \]

Verify no augmenting path remains

Why: Both edges leaving s, s to a and s to b, are now saturated with forward residual 0, so nothing can leave s in the residual graph. The algorithm halts with value 2, matching the true maximum found earlier. Choosing shortest paths reached the same answer as the back-edge route, without needing to traverse a back edge at all on this particular network.

69. An Edmonds-Karp trace — line by line

Picture it

Animation

Shows: Each line of the worked example "An Edmonds-Karp trace", appearing one at a time.

The same working the example does, in the order a tutor would write it.

Takeaway: Both edges leaving s, s to a and s to b, are now saturated with forward residual 0, so nothing can leave s in the residual graph. The algorithm halts with value 2, matching the true maximum found earlier. Choosing shortest paths reached the same answer as the back-edge route, without needing to traverse a back edge at all on this particular network.

70. Edmonds-Karp's running time

Concept

Because always taking a shortest path bounds how many augmentations can happen, Edmonds-Karp runs in time polynomial in the size of the network, regardless of how large the edge capacities are.

\[ O(V \cdot E^{2}) \]

V is the number of nodes and E is the number of edges. The exact bound is a fact to remember, not something to re-derive here, but the key point is that it does not depend on the capacities at all, unlike an arbitrary choice of augmenting paths.

71. The Ford-Fulkerson / Edmonds-Karp recipe

Pattern

1. Start with the zero flow

Why: Every edge begins carrying nothing. This is always a valid flow, since 0 is within every capacity and conservation trivially holds.

2. Build the residual graph from the current flow

Why: Forward edges get leftover capacity, capacity minus flow. Backward edges get residual capacity equal to the current flow, wherever flow exists.

3. Find an augmenting path from s to t (shortest, for Edmonds-Karp)

Why: Any path where every edge, forward or backward, has positive residual capacity. Edmonds-Karp specifically uses breadth-first search to find a shortest one.

4. Augment by the bottleneck, then repeat

Why: Raise flow on forward edges and lower flow on edges whose back edge was used, by the path's minimum residual capacity. Rebuild the residual graph and search again. Stop only when no augmenting path exists.

72. Rule out three: Check yourself: is this an augmenting path?

Elimination

Eliminate the wrong options

Which of these is a valid augmenting path in the residual graph at this point?

3 of these 4 are wrong. Strike them one at a time, and say what rules each one out before you strike the next. The survivor is the answer.

  • A. s to b, then the back edge b to a, then a to t
  • B. s to a, then a to b, then b to t
  • C. s to a, then a to t
  • D. s to b, then b to t

Survives elimination: A

Why: Check every edge: s to b has forward residual 1 (untouched), the back edge b to a has residual capacity equal to the flow on a to b, which is 1, and a to t has forward residual 1 (untouched). All three are positive, so the full path is augmenting.

73. Check yourself: is this an augmenting path?

Check

Right after the greedy step sends 1 unit along s to a to b to t (so f(s,a)=1, f(a,b)=1, f(b,t)=1, and f(s,b)=f(a,t)=0), consider four candidate paths from s to t.

Check your understanding

Which of these is a valid augmenting path in the residual graph at this point?

  • A. s to b, then the back edge b to a, then a to t (correct)
  • B. s to a, then a to b, then b to t
  • C. s to a, then a to t
  • D. s to b, then b to t

Answer: A

Why: Check every edge: s to b has forward residual 1 (untouched), the back edge b to a has residual capacity equal to the flow on a to b, which is 1, and a to t has forward residual 1 (untouched). All three are positive, so the full path is augmenting.

Why B tempts people
This repeats the edges already saturated by the greedy step. s to a, a to b, and b to t each have forward residual 0 right now, since they are already carrying their full capacity.
Why C tempts people
The second edge a to t does have residual 1, but the first edge s to a is already saturated (forward residual 0) from the greedy step, so the path is blocked at its very first edge.
Why D tempts people
The first edge s to b does have residual 1, but the second edge b to t is already saturated (forward residual 0) from the greedy step, so the path is blocked at its second edge.

74. The Max-Flow Min-Cut Theorem

Section

Section 4

75. What is an s-t cut

Concept

An s-t cut splits every node in the network into two groups: one group containing the source, the other containing the sink.

s-t cut — A split of all nodes into two sets S and T, where the source is in S and the sink is in T. Written as the pair (S,T).

Any such split is a valid cut, no matter how the internal nodes are distributed between the two sides, as long as s ends up in S and t ends up in T.

76. The capacity of a cut

Concept

A cut's capacity only counts edges crossing from the S side to the T side, in that direction. Edges running from T back to S, or edges with both ends on the same side, are not counted at all.

cut capacity — The sum of capacities of every edge that starts in S and ends in T. Edges from T to S do not count toward it, even if they exist.

\[ c(S,T) \;=\; \sum_{u \in S,\ v \in T} c(u,v) \]

77. The tightest bottleneck

Intuition

Every unit of flow leaving s and reaching t must, at some point, cross from the S side to the T side of any cut you pick. So a cut's capacity is an upper limit on how much flow could possibly get through, no matter how cleverly it is routed.

Some cuts are generous, with a huge combined capacity. Others are tight bottlenecks. The tightest one of all turns out to say something exact about the maximum flow, not just an approximate bound.

78. Picture it first: Compute a cut's capacity

Picture it

Figure (svg): The s, a, b, t network with a dashed boundary separating s alone on the S side from a, b, t on the T side. The two crossing edges, s to a and s to b, are highlighted in red as the cut edges.

Discussion prompt

Read the picture before the words. What is this showing, and what is the one thing it is built to make obvious? Commit to an answer, then read on.

Hint: Name the parts, then say what changes between them — and if nothing changes, say what is being held still.

Answer:

On the s, a, b, t network, consider the cut with S containing only s, and T containing a, b, and t.

79. Compute a cut's capacity

Worked example

On the s, a, b, t network, consider the cut with S containing only s, and T containing a, b, and t.

Figure (svg): The s, a, b, t network with a dashed boundary separating s alone on the S side from a, b, t on the T side. The two crossing edges, s to a and s to b, are highlighted in red as the cut edges.

List every edge from S to T

Why: S contains only s. The edges leaving s are s to a and s to b, and both end in T. No other edge starts in S, since S has only one node.

edgefrom sideto sidecounts toward cut
s to aSTyes
s to bSTyes
a to bTTno
a to tTTno
b to tTTno

Add up their capacities

Why: Only s to a and s to b cross from S to T. The edges a to b, a to t, and b to t all sit entirely inside T, so none of them count.

\[ c(S,T) = c(s,a) + c(s,b) = 1 + 1 = 2 \]

Verify by counting what could not possibly be excluded

Why: Every edge leaving S was included exactly once, and no edge inside T or entering S was counted. The capacity of this cut is 2.

80. What stays fixed: Compute a cut's capacity

Invariant

Step through it

Step through Compute a cut's capacity one row at a time. One of these columns never changes — find it, and say why it cannot.

  1. Step 1: edge is s to a
  2. Step 2: edge is s to b
  3. Step 3: edge is a to b
  4. Step 4: edge is a to t
  5. Step 5: edge is b to t

81. Decision point: how would you ever know a flow is maximum?

Intuition

What move should we make next?

You have a flow of value 23. You have searched and found no augmenting path.

\[ |f| = 23, \qquad \text{is 24 possible?} \]

Not finding a path is evidence about your search, not about the network.

You need something that rules out 24 for every possible flow, not just yours. What kind of object would do that, and have you seen this pattern before?

_Look at your toolkit. Say a move number out loud before this slide advances._ A wrong guess is useful. A silent guess is not.

82. Weak duality: flow never beats any cut

Concept

Here is the easier half of the big theorem: no matter which flow you have and which cut you pick, the flow's value can never exceed that cut's capacity.

\[ |f| \;\le\; c(S,T) \qquad \text{for every flow } f \text{ and every cut } (S,T) \]

The reasoning is simple: every unit of flow leaving s must eventually cross from S to T to reach t, and the edges crossing that way cannot carry more than their combined capacity, the cut's capacity.

83. The Certificate skeleton

Concept

Every proof of this kind has the same five or six moves in the same order. The order is not something you rediscover each time.

It is on the right. It will stay on the right through the worked examples that follow.

Why this matters: the structure is now handled. You are not spending working memory on what comes next — you are spending all of it on the one hard step.

Step 2 is usually easy and step 4 is one line. Step 3 is the whole theorem — you must actually construct the matching object, not merely argue one exists.

84. The final move, named

Concept

The move: #16 (Certificate of optimality).

Prove a ceiling that applies to every solution

Why: Every flow crossing any s-t cut is bounded by that cut's capacity. So every cut is a ceiling on every flow, forever, regardless of what algorithm produced it.

\[ |f| \le c(S, T) \quad \text{for every flow } f \text{ and every cut } (S, T) \]

Then exhibit one instance of the ceiling that equals your value

Why: Find a specific cut whose capacity is exactly 23. Now no flow can exceed 23, and yours achieves it — so yours is maximum and that cut is minimum, both settled at once.

Say where the certificate comes from

Why: Take the vertices reachable from the source in the final residual graph. That set is the cut, and it is read straight off the algorithm's final state — not searched for separately.

This is what proof gives you that testing cannot. No amount of running the algorithm establishes that 24 is impossible; one cut of capacity 23 establishes it permanently.

85. What has to happen first: Verify weak duality against three cuts

Ranking

Put in order

Put the moves of Verify weak duality against three cuts into the order they have to happen.

  1. Cut 1: S is s alone
  2. Cut 2: S is s and a together
  3. Cut 3: S is s, a, and b together
  4. Verify: the flow's value never exceeded any cut's capacity

Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. Only s to a and s to b cross, both capacity 1, giving cut capacity 2.

86. Verify weak duality against three cuts

Worked example

The maximum flow found earlier on the s, a, b, t network has value 2. Check that this value is at most the capacity of several different cuts.

Cut 1: S is s alone

Why: Only s to a and s to b cross, both capacity 1, giving cut capacity 2.

\[ c(S,T) = 1 + 1 = 2 \quad \ge\quad |f| = 2 \]

Cut 2: S is s and a together

Why: Now the crossing edges are s to b (s is in S, b is in T) and a to t (a is in S, t is in T), plus a to b (a in S, b in T). That is three crossing edges, capacity 1 each.

\[ c(S,T) = c(s,b) + c(a,b) + c(a,t) = 1+1+1 = 3 \quad \ge\quad |f| = 2 \]

Cut 3: S is s, a, and b together

Why: Now only a to t and b to t cross into T, which contains just t. Capacity 1 each.

\[ c(S,T) = c(a,t) + c(b,t) = 1+1 = 2 \quad \ge\quad |f| = 2 \]

Verify: the flow's value never exceeded any cut's capacity

Why: 2 is at most 2, at most 3, and at most 2 again. Weak duality held in every case, and two of these three cuts, capacity 2, are exactly tied with the flow's value. That tie is not a coincidence, it is what the full theorem is about.

87. Verify weak duality against three cuts — line by line

Picture it

Animation

Shows: Each line of the worked example "Verify weak duality against three cuts", appearing one at a time.

The same working the example does, in the order a tutor would write it.

Takeaway: 2 is at most 2, at most 3, and at most 2 again. Weak duality held in every case, and two of these three cuts, capacity 2, are exactly tied with the flow's value. That tie is not a coincidence, it is what the full theorem is about.

88. Decision point: three statements, all equivalent

Intuition

What move should we make next?

The theorem says these three are the same statement:

  1. The flow is maximum.
  2. The residual graph has no augmenting path.
  3. There is a cut whose capacity equals the flow value.

Which of the three implications is nearly free, and which one requires you to build something? Name the move for the hard one.

_Look at your toolkit. Say a move number out loud before this slide advances._ A wrong guess is useful. A silent guess is not.

89. The max-flow min-cut theorem

Concept

Weak duality says the maximum possible flow can never beat the smallest cut's capacity. The max-flow min-cut theorem says something much stronger: they are always exactly equal.

max-flow min-cut theorem — In any flow network, the value of a maximum flow equals the capacity of a minimum s-t cut. Neither one can ever be smaller than the other.

\[ \max_{f} |f| \;=\; \min_{(S,T)} c(S,T) \]

This is what makes flow algorithms trustworthy: whenever an algorithm halts with no augmenting path left, it has automatically also produced a cut with matching capacity, which is proof, on the spot, that no larger flow could ever exist.

90. Max-flow equals min-cut

Picture it

Animation

Shows: Max-flow equals min-cut — a rendered Manim animation.

Rendered with Manim.

Takeaway: Two very different-looking quantities, provably identical.

91. Picture it first: Verify the theorem end-to-end

Picture it

Figure (svg): The final residual graph: s has no outgoing residual edges at all, since s to a and s to b are both saturated, while a to b remains open with residual 1 and four dashed amber back edges point into s, a, and b from the saturated edges.

Discussion prompt

Read the picture before the words. What is this showing, and what is the one thing it is built to make obvious? Commit to an answer, then read on.

Hint: Name the parts, then say what changes between them — and if nothing changes, say what is being held still.

Answer:

Take the final residual graph of the s, a, b, t network at its maximum flow of value 2, where f(s,a)=1, f(s,b)=1, f(a,b)=0, f(a,t)=1, f(b,t)=1.

92. Verify the theorem end-to-end

Worked example

Take the final residual graph of the s, a, b, t network at its maximum flow of value 2, where f(s,a)=1, f(s,b)=1, f(a,b)=0, f(a,t)=1, f(b,t)=1.

Figure (svg): The final residual graph: s has no outgoing residual edges at all, since s to a and s to b are both saturated, while a to b remains open with residual 1 and four dashed amber back edges point into s, a, and b from the saturated edges.

Find every node reachable from s in this residual graph

Why: Both edges leaving s in the original graph, s to a and s to b, are saturated, so their forward residual is 0. No other edge starts at s. Therefore s can reach nothing at all, and the reachable set is just s itself.

\[ S = \{s\}, \qquad T = \{a,b,t\} \]

Read off the cut this defines

Why: This S and T form a genuine s-t cut, and its capacity is the sum of the original capacities of edges leaving S: s to a plus s to b.

\[ c(S,T) = c(s,a) + c(s,b) = 1 + 1 = 2 \]

Verify the max flow equals this cut's capacity

Why: The maximum flow found by hand earlier has value 2, and this cut also has capacity 2. They match exactly, confirming the theorem on this network: this cut is a minimum cut, and 2 is truly the maximum flow, not just a flow someone happened to stop at.

\[ |f^{*}| = 2 = c(S,T) \]

93. Work backwards from the answer: Verify the theorem end-to-end

Reverse engineer

Discussion prompt

Work backwards. The example finished here:

Verify the max flow equals this cut's capacity

What was it asked to do, and what must it have been given? Reconstruct the problem from its answer.

Hint: Every quantity in the result had to enter somewhere. Account for each one.

Answer:

Take the final residual graph of the s, a, b, t network at its maximum flow of value 2, where f(s,a)=1, f(s,b)=1, f(a,b)=0, f(a,t)=1, f(b,t)=1.

94. Something is wrong here: max flow and min cut are not just "related"

Anomaly

Predict first

A student writes this, and it looks reasonable:

A student computes the maximum flow one way, gets a value, then separately estimates a cut's capacity a different, sloppier way, gets a different number, and concludes the two ideas are merely related but not actually equal.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: This treats the theorem as a rough rule of thumb rather than an exact equality.

The theorem is an exact equality, always. If a computed flow value and a computed cut capacity disagree, one of the two computations has a mistake in it, not the theorem.

Why: This treats the theorem as a rough rule of thumb rather than an exact equality. In fact the mismatch is a signal that the cut was computed wrong, most likely by counting an edge that runs from T back to S, or an edge that sits entirely inside one side, which never counts toward a cut's capacity.

95. Trap: max flow and min cut are not just "related"

Trap

The trap

A student computes the maximum flow one way, gets a value, then separately estimates a cut's capacity a different, sloppier way, gets a different number, and concludes the two ideas are merely related but not actually equal.

\[ \text{their flow: } 2 \qquad \text{their "cut": } 3 \ (\text{miscounted}) \]

Accept the mismatch as normal

Why: This treats the theorem as a rough rule of thumb rather than an exact equality. In fact the mismatch is a signal that the cut was computed wrong, most likely by counting an edge that runs from T back to S, or an edge that sits entirely inside one side, which never counts toward a cut's capacity.

The fix

The theorem is an exact equality, always. If a computed flow value and a computed cut capacity disagree, one of the two computations has a mistake in it, not the theorem.

\[ \max_{f}|f| \;=\; \min_{(S,T)} c(S,T) \quad \text{(always, no exceptions)} \]

Recompute the cut, counting only S-to-T edges

Why: For S equal to s alone, only s to a and s to b cross, giving capacity 2, not 3. Once counted correctly, the cut's capacity is exactly 2, matching the flow's value exactly. There is no gap to explain away.

\[ c(S,T) = c(s,a) + c(s,b) = 2 = |f^{*}| \]

96. Break it on purpose: max flow and min cut are not just "related"

Break the constraint

Discussion prompt

The rule this trap just fixed:

The theorem is an exact equality, always. If a computed flow value and a computed cut capacity disagree, one of the two computations has a mistake in it, not the theorem.

Now break it on purpose. Build a case that violates it and follow the consequences until something visibly fails. Where does the failure first show up — and would you have noticed it if you had not been looking?

Hint: The dangerous rules are the ones whose violation still produces an answer. If yours fails loudly, try to find one that fails quietly.

Answer:

This treats the theorem as a rough rule of thumb rather than an exact equality. In fact the mismatch is a signal that the cut was computed wrong, most likely by counting an edge that runs from T back to S, or an edge that sits entirely inside one side, which never counts toward a cut's capacity.

97. Reading a minimum cut off the residual graph

Pattern

1. Run the flow algorithm to completion

Why: Keep augmenting until the residual graph has no path left from s to t. What remains is a maximum flow.

2. Find every node reachable from s in the final residual graph

Why: Search forward and backward residual edges alike, starting at s. Call this reachable set S, and everything else T.

3. Read the cut edges from the original graph, not the residual one

Why: The minimum cut's capacity is the sum of original capacities on edges that start in S and end in T, using the real network, not residual capacities.

4. Confirm the capacity equals the flow's value

Why: By the theorem, this always matches. If it does not, recheck which edges were counted as crossing from S to T.

98. Where this shows up: Network Flow: Max-Flow Min-Cut

Real world

Discussion prompt

Outside this lesson: where does Network Flow: Max-Flow Min-Cut actually turn up? Name one concrete situation — a job, a piece of software someone ships, a decision somebody has to make — and say which part of Reading a minimum cut off the residual graph is doing the work in it.

Hint: Vague is the failure mode here. "Engineering" is not a situation; "deciding whether this build is fast enough to ship" is.

Answer:

Flow networks, the two rules a valid flow obeys, residual graphs and why augmenting paths need back edges, Ford-Fulkerson and Edmonds-Karp, the max-flow min-cut theorem, and the bipartite-matching reduction. Targets four real misconceptions: exceeding an edge's capacity, forgetting residual back edges, confusing the max-flow value with the min-cut capacity, and assuming a single greedy highest-capacity path finishes the job.

99. Answer it before you see the options: Check yourself: what must be true?

Prediction

Predict first

According to the max-flow min-cut theorem, what must be true of every s-t cut in that network?

Answer it in your own words, now, with nothing to choose from. The options are on the next slide — and picking the right one off a list is an easier skill than producing it.

Correct: Every cut has capacity at least 7, and at least one cut has capacity exactly 7.

Why: Weak duality guarantees every cut's capacity is at least the maximum flow's value, so at least 7 for every cut. The theorem additionally guarantees the minimum cut achieves exact equality with the maximum flow, so some cut has capacity exactly 7.

100. Check yourself: what must be true?

Check

Suppose you are told that the maximum flow in some network has value 7.

Check your understanding

According to the max-flow min-cut theorem, what must be true of every s-t cut in that network?

  • A. Every cut has capacity at least 7, and at least one cut has capacity exactly 7. (correct)
  • B. Every cut has capacity exactly 7.
  • C. Every cut has capacity at most 7.
  • D. The maximum flow and the minimum cut are usually different numbers; exact equality is rare.

Answer: A

Why: Weak duality guarantees every cut's capacity is at least the maximum flow's value, so at least 7 for every cut. The theorem additionally guarantees the minimum cut achieves exact equality with the maximum flow, so some cut has capacity exactly 7.

Why B tempts people
This assumes every cut is a minimum cut. Only the smallest cut is forced to equal 7; larger, non-minimal cuts can have capacity well above 7, as seen with the capacity-3 cut on the s, a, b, t network.
Why C tempts people
This reverses weak duality's direction. A cut's capacity is an upper bound the flow cannot exceed, not an upper bound on the cut itself; cuts can be arbitrarily large, never smaller than the max flow.
Why D tempts people
This directly contradicts the theorem. The theorem guarantees exact equality between the maximum flow and the minimum cut in every flow network, always, not occasionally.

101. Bipartite Matching as Flow

Section

Section 5

102. The bipartite matching problem

Concept

A bipartite graph has two separate groups of nodes, Left and Right, with edges only running between the groups, never within a group.

matching — A set of edges in a bipartite graph where no two chosen edges share an endpoint. Each Left node is paired with at most one Right node, and vice versa.

The goal is usually a maximum matching: the largest possible set of such non-overlapping pairs. This models job assignment, roommate pairing, and many scheduling problems.

103. Matching, reduced to flow

Picture it

Animation

Shows: Matching, reduced to flow — a rendered Manim animation.

Rendered with Manim.

Takeaway: A different problem, solved by the machinery you already built.

104. Perfect matching versus maximum matching

Concept

A perfect matching pairs up every single node on both sides, with nobody left out. It only exists when the two sides are the same size and the edges cooperate.

perfect matching — A matching that covers every node on both the Left and Right sides. Every perfect matching is a maximum matching, but not every maximum matching is perfect.

A maximum matching always exists (it might just be empty in the worst case), but a perfect matching might not, if the available edges simply do not allow everyone to be paired.

105. Matching as flow

Intuition

Picture every Left node sending a single unit of supply, and every Right node able to absorb only a single unit of demand. An edge between a Left and Right node is a route that one unit can travel along, but never more than one.

That single-unit restriction is exactly what an edge capacity of 1 enforces. Once the whole picture is a flow network, finding the biggest matching becomes finding the biggest flow.

106. Integer capacities give integer flows

Picture it

Animation

Shows: Integer capacities give integer flows — a rendered Manim animation.

Rendered with Manim.

Takeaway: Which is what lets flow solve matching problems.

107. Building the flow network from a bipartite graph

Concept

Add one new source node connected to every Left node, and one new sink node that every Right node connects to. Give every added edge, and every original edge, capacity 1.

\[ c(s, \ell) = 1 \ \forall \ell \in \text{Left}, \qquad c(\ell, r) = 1 \ \text{for each original edge}, \qquad c(r, t) = 1 \ \forall r \in \text{Right} \]

A maximum flow in this new network has an integer value, since every capacity is a whole number, and that integer flow translates directly back into a matching: an edge between a Left and Right node is part of the matching exactly when it carries flow 1.

108. Picture it first: Solve a matching problem with max flow

Picture it

Figure (svg): A bipartite flow network: a source connects to L1, L2, and L3, each with capacity 1. L1 connects to R1, L2 connects to both R1 and R2, and L3 connects to R2, each edge capacity 1. R1 and R2 each connect to a sink with capacity 1.

Discussion prompt

Read the picture before the words. What is this showing, and what is the one thing it is built to make obvious? Commit to an answer, then read on.

Hint: Name the parts, then say what changes between them — and if nothing changes, say what is being held still.

Answer:

Three workers, L1, L2, L3, and two tasks, R1, R2. L1 can only do R1. L2 can do either R1 or R2. L3 can only do R2. Model this as flow and find the maximum matching.

109. Solve a matching problem with max flow

Worked example

Three workers, L1, L2, L3, and two tasks, R1, R2. L1 can only do R1. L2 can do either R1 or R2. L3 can only do R2. Model this as flow and find the maximum matching.

Figure (svg): A bipartite flow network: a source connects to L1, L2, and L3, each with capacity 1. L1 connects to R1, L2 connects to both R1 and R2, and L3 connects to R2, each edge capacity 1. R1 and R2 each connect to a sink with capacity 1.

Notice the bottleneck before computing anything

Why: Only two edges lead into the sink, R1 to t and R2 to t, each capacity 1. No matter how generous the Left side is, the sink can never absorb more than 2 units total.

\[ \text{max possible flow} \le c(R1,t) + c(R2,t) = 1 + 1 = 2 \]

Send flow along s to L1 to R1 to t

Why: Every edge on this path has capacity 1 and is untouched, so the bottleneck is 1. This matches L1 with R1.

\[ f(s,L1)=1,\ f(L1,R1)=1,\ f(R1,t)=1 \]

Send flow along s to L3 to R2 to t

Why: This path is also untouched, bottleneck 1. This matches L3 with R2.

\[ f(s,L3)=1,\ f(L3,R2)=1,\ f(R2,t)=1, \quad \text{total value} = 2 \]

Verify no augmenting path remains, and read off the matching

Why: Both edges into t are now saturated, so no more flow can reach the sink; the max flow is 2, matching the bottleneck spotted at the start. L2 carries no flow, since both R1 and R2 are already taken. The matching is L1 with R1 and L3 with R2, size 2, which is the maximum matching for this bipartite graph.

110. Decode the notation: Solve a matching problem with max flow

Notation

Annotate

From Solve a matching problem with max flow — read this one piece at a time. What is each part doing?

On: \( f(s,L3)=1,\ f(L3,R2)=1,\ f(R2,t)=1, \quad \text{total value} = 2 \)

  • Only two edges lead into the sink, R1 to t and R2 to t, each capacity 1. No matter how generous the Left side is, the sink can never absorb more than 2 units total.
  • Every edge on this path has capacity 1 and is untouched, so the bottleneck is 1. This matches L1 with R1.
  • This path is also untouched, bottleneck 1. This matches L3 with R2.

111. Why capacity-1 edges keep the flow honest

Concept

Capacity 1 on every source-to-Left and Right-to-sink edge is not a simplification, it is what makes the translation back to a matching valid at all.

\[ f(s,\ell) \le 1 \ \Rightarrow\ \ell \text{ is used in at most one matched pair} \]

Because the maximum flow here is always an integer (every capacity is a whole number), each Left node either sends its single unit down exactly one Left-Right edge, or sends nothing. That is precisely what being matched to at most one partner means.

112. Back edges let the algorithm change its mind

Picture it

Animation

Shows: Back edges let the algorithm change its mind — a rendered Manim animation.

Rendered with Manim.

Takeaway: Without them a greedy first choice could never be undone, and the answer would be wrong.

113. Something is wrong here: forgetting the capacity-1 edges

Anomaly

Predict first

A student writes this, and it looks reasonable:

A student builds the same source and sink but leaves the source-to-Left edges without a capacity limit, thinking capacity only matters for the original bipartite edges.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: With no cap on s to L2, a max-flow algorithm is free to push 1 unit through each of L2's two edges simultaneously, for a total of 2 units leaving L2.

Every source-to-Left edge, and every Right-to-sink edge, must have capacity exactly 1, the same as the original bipartite edges.

Why: With no cap on s to L2, a max-flow algorithm is free to push 1 unit through each of L2's two edges simultaneously, for a total of 2 units leaving L2. That would mean L2 is matched to two tasks at the same time, which is not a matching at all.

114. Trap: forgetting the capacity-1 edges

Trap

The trap

A student builds the same source and sink but leaves the source-to-Left edges without a capacity limit, thinking capacity only matters for the original bipartite edges.

\[ c(s, L2) = \infty \ \text{(mistakenly uncapped)} \]

Let L2 send flow along both L2 to R1 and L2 to R2 at once

Why: With no cap on s to L2, a max-flow algorithm is free to push 1 unit through each of L2's two edges simultaneously, for a total of 2 units leaving L2. That would mean L2 is matched to two tasks at the same time, which is not a matching at all.

The fix

Every source-to-Left edge, and every Right-to-sink edge, must have capacity exactly 1, the same as the original bipartite edges.

\[ c(s, L2) = 1 \]

Cap L2's supply at 1 unit total

Why: With c(s, L2) = 1, conservation at L2 forces its total outgoing flow to also be at most 1, so at most one of L2 to R1 or L2 to R2 can carry flow. L2 ends up matched to at most one task, exactly as a valid matching requires.

115. Which of these survive contact with Network Flow: Max-Flow Min-Cut?

Two truths and a lie

Sort into buckets

Some of these hold up and some are the exact mistakes this lesson is built to prevent. Sort them.

Holds up
You have named 15 reusable moves so far. Say as many as you can out loud, by number, from memory.; A flow network is a directed graph built for one job: moving something from a single starting point to a single ending point.; An edge from s to a with capacity 1 says nothing about a direction from a back to s. If that reverse edge is not drawn in the network, its capacity is 0.
Breaks
A student wants more flow through the network fast, so they push 2 units across the edge from s to a, whose capacity is only 1.; In that forward-only picture, the only edges with residual capacity are s to b and a to t, and they do not connect to each other (no edge from b to a exists going forward).
sound
These are stated as this lesson states them — each one survives the edge cases Network Flow: Max-Flow Min-Cut puts it through.
flawed
Each of these is lifted from a trap in this deck: reasonable-sounding, and wrong in a way that only shows up once you rely on it.

116. Check yourself: reading off a matching

Check

In the bipartite matching flow network above, capacity 1 everywhere, suppose a completed maximum flow has value 2 while there are 3 Left nodes total.

Check your understanding

What can you correctly conclude?

  • A. The maximum matching has exactly 2 pairs; at least one Left node cannot be matched given the available edges. (correct)
  • B. The maximum matching must have 3 pairs, since there are 3 Left nodes.
  • C. A flow value of 2 means no valid matching exists at all.
  • D. The edge capacities need to be raised above 1 to find a bigger matching.

Answer: A

Why: The maximum flow's value equals the maximum matching's size exactly, by construction. A value of 2 out of 3 possible Left nodes means the largest matching achievable with these edges pairs up only 2 of the 3 Left nodes; the third has no compatible, unused Right node.

Why B tempts people
This assumes every Left node can always be matched, ignoring that matching depends on which edges actually exist. If the available edges do not allow a third pair, the maximum stays at 2 no matter how many Left nodes there are.
Why C tempts people
A flow value of 2 is a perfectly valid, nonzero matching of size 2, not a failure. It is simply not a perfect matching, which is a different, stronger requirement.
Why D tempts people
Raising the capacities above 1 would break the reduction's correctness (a single Left node could then be matched to more than one task at once); it does not fix a genuine lack of compatible edges.

117. Beyond Flow

Section

Section 6

118. Many hard-looking problems reduce to flow

Concept

Bipartite matching is just one example of a problem that looks like it needs its own separate algorithm, but turns out to be a flow problem in disguise once you find the right source, sink, and capacities.

119. Every flow problem here is solved efficiently

Concept

This is the reassuring part: every one of those reductions inherits Edmonds-Karp's guarantee. Once a problem is reduced to max flow, it is solved in time polynomial in the size of the input, no matter how large the network gets.

That is not true of every problem you will meet this term. Flow sits on the fortunate side of a line that runs through the rest of the course.

120. The bridge to NP-completeness

Concept

Flow problems always yield to an efficient algorithm, but plenty of other problems that sound just as reasonable to state do not have any known efficient algorithm at all.

The rest of this course turns to exactly that gap: how to recognize a problem that likely has no efficient algorithm, a property called NP-completeness, and what to do about it when you meet one.

121. Teach it back: The bridge to NP-completeness

Explain it

Discussion prompt

Explain The bridge to NP-completeness to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.

Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.

Answer:

Flow problems always yield to an efficient algorithm, but plenty of other problems that sound just as reasonable to state do not have any known efficient algorithm at all.

122. Decision point: account for the whole course

Intuition

What move should we make next?

Sixteen named moves, eighteen lessons, one final exam.

Close the deck. Write all sixteen from memory, in order, with a one-line description of each.

Then, for any proof from any lesson this term, you should be able to name the moves it used. If you can do that, you are not memorizing proofs any more.

_Look at your toolkit. Say a move number out loud before this slide advances._ A wrong guess is useful. A silent guess is not.

123. By analogy: Decision point: account for the whole course

Analogy

Discussion prompt

Explain Decision point: account for the whole course by analogy to something with no CS3000 Algorithms in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.

Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.

Answer:

Sixteen named moves, eighteen lessons, one final exam.

124. Rule out three: Check yourself: a full max-flow computation

Elimination

Eliminate the wrong options

What is the maximum flow from s to t in this network?

3 of these 4 are wrong. Strike them one at a time, and say what rules each one out before you strike the next. The survivor is the answer.

  • A. 5
  • B. 11
  • C. 4
  • D. 3

Survives elimination: A

Why: Send 2 along s-x-t and 2 along s-y-t (total 4), saturating x-t and s-y. One more augmenting path remains, s to x to y to t with bottleneck 1 (using the leftover residual capacity 1 on s-x and the untouched edge x-y and the leftover residual capacity 1 on y-t), bringing the total to 5. Now both edges leaving s, s-x and s-y, are saturated, so no augmenting path remains. This matches the cut capacity(s,x) + capacity(s,y) = 3 + 2 = 5.

125. Check yourself: a full max-flow computation

Check

A new network: s to x (capacity 3), s to y (capacity 2), x to y (capacity 1), x to t (capacity 2), y to t (capacity 3).

edgecapacity
s to x3
s to y2
x to y1
x to t2
y to t3

Check your understanding

What is the maximum flow from s to t in this network?

  • A. 5 (correct)
  • B. 11
  • C. 4
  • D. 3

Answer: A

Why: Send 2 along s-x-t and 2 along s-y-t (total 4), saturating x-t and s-y. One more augmenting path remains, s to x to y to t with bottleneck 1 (using the leftover residual capacity 1 on s-x and the untouched edge x-y and the leftover residual capacity 1 on y-t), bringing the total to 5. Now both edges leaving s, s-x and s-y, are saturated, so no augmenting path remains. This matches the cut capacity(s,x) + capacity(s,y) = 3 + 2 = 5.

Why B tempts people
This adds up every capacity in the whole network, 3+2+1+2+3, which has no meaning for max flow; only the capacities of edges crossing a chosen cut ever get summed together.
Why C tempts people
This stops after only the first two obvious paths, s-x-t and s-y-t (2 plus 2), without checking the residual graph for a further augmenting path through x to y. Exactly like the fattest-pipe trap, one more unit is still available.
Why D tempts people
This takes only the larger of the two edges leaving s, s-x with capacity 3, and assumes that single edge is the whole bottleneck, ignoring that s-y (capacity 2) is a separate route that also contributes to the total leaving s.

126. Watch it run: Check yourself: a full max-flow computation

Pattern

Step through it

Step through Check yourself: a full max-flow computation one row at a time. What is driving the change, and what would the row after the last one be?

  1. Step 1: edge is s to x
  2. Step 2: edge is s to y
  3. Step 3: edge is x to y
  4. Step 4: edge is x to t
  5. Step 5: edge is y to t

127. Toolkit update

Concept

Moves added today:

Moves you reused today:

That is the full toolkit: 16 named moves, built across 18 lessons. Every proof in this course was some arrangement of them. Nothing on the final will need a seventeenth.

Full toolkit so far: #1 through #16.

Next session opens with you naming every one of these from memory, before any new material.

128. Break it if you can: Toolkit update

Counterexample

Discussion prompt

Next session opens with you naming every one of these from memory, before any new material.

That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.

Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.

129. Connect it up: Network Flow: Max-Flow Min-Cut

Connect it up

Draw it

One page, no notation unless you need it: draw how these connect — Flow Networks: The Basics · Residual Graphs & Augmenting Paths · Ford-Fulkerson & Edmonds-Karp · The Max-Flow Min-Cut Theorem · Bipartite Matching as Flow · Beyond Flow. Put an arrow wherever one of them is what makes another possible, and label the arrow with why.

130. What you can do now

Recap

You can now read, build, and reason about flow networks from the ground up.

IdeaThe one thing to remember
Valid flowCapacity limit and conservation, at every internal node
Residual graphForward = leftover capacity; backward = flow available to undo
Ford-Fulkerson / Edmonds-KarpAugment until none remain; shortest path first stays fast
Max-flow min-cutMaximum flow value equals minimum cut capacity, always

Sources

  1. Cormen, Leiserson, Rivest, Stein, Introduction to Algorithms, 3rd ed., Ch. 26: Maximum Flow — MIT Press, 2009.
  2. Kleinberg & Tardos, Algorithm Design, Ch. 7: Network Flow — Addison-Wesley, 2006.
  3. All flow traces, residual graphs, cut capacities, and matching reductions in this deck were recomputed by hand, edge by edge. — Verified 2026-07-18.
  4. Northeastern University CS 3000, Algorithms and Data (Summer 2026) — course page and syllabus — course.ccs.neu.edu/cs3000su26. Sets Cormen, Leiserson, Rivest and Stein, Introduction to Algorithms (3rd ed.) as the textbook; listings follow its conventions.
  5. CS 3000 course notes and midterm references circulated by students — github.com/vigneshsaravanakumar404/CS-3000-Algorithms-Data. Notes are typeset with the algpseudocode package, which is the style the listings in this deck follow.

Want this taught 1-on-1? Alexander tutors CS3000 Algorithms — $55/session, free consultation.

Book on Wyzant · Text (657) 465-8108