Ford-Fulkerson Method
Picture a network of pipes carrying oil from a single source refinery to a single destination port. Each pipe has a maximum capacity. How much oil can flow from source to destination per unit time? Along which pipes should it travel? This is the maximum flow problem. It shows up far beyond literal pipelines. Routing internet packets, scheduling airline crews, matching applicants to jobs, and segmenting images in computer vision all reduce to finding a maximum flow. Each of these problems maps onto a suitably constructed graph. The Ford-Fulkerson method, introduced in 1956, gives the first general algorithmic answer. It repeatedly finds a path along which more flow can still be pushed. It pushes as much as possible along that path. This repeats until no such path exists. The elegance of the method lies in a clever bookkeeping device called the residual graph. This device lets the algorithm "undo" earlier bad routing decisions by pushing flow backward. This single idea — augmenting paths in a residual graph — is the ancestor of nearly every modern max-flow algorithm. Ford-Fulkerson is officially a method rather than a fully specified algorithm. This is because it does not say which augmenting path to pick. Chosen carelessly, it can be shockingly slow. It can even fail to terminate on irrational capacities. Chosen wisely — via breadth-first search — it becomes the Edmonds-Karp refinement. This gives a clean polynomial-time algorithm with a satisfying complexity proof. This article develops the method in full. It covers the residual graph construction and the augmenting-path loop. It explains why the method terminates and returns a correct answer. It also covers the specific pathologies that arise from bad path choices. Finally, it shows how BFS tames them into a provably efficient algorithm. Understanding Ford-Fulkerson is also the cleanest route into one of the most beautiful theorems in combinatorial optimization. That theorem is the Max-Flow Min-Cut Theorem. It also directly powers algorithms for Bipartite Matching via Augmenting Paths. Everything here builds on Network Flow Fundamentals. It uses Breadth-First Search as a core subroutine.
- Max flow is computed by repeatedly finding an augmenting path from source to sink in a residual graph and pushing flow along it.
- The residual graph encodes both remaining forward capacity and the ability to cancel previously sent flow via reverse edges.
- The method terminates when no augmenting path exists; at that point the current flow is provably maximum.
- With arbitrary path selection and irrational capacities, Ford-Fulkerson can fail to terminate; with integer capacities it terminates but can take pseudo-polynomial time.
- Edmonds-Karp picks the shortest augmenting path (via BFS), guaranteeing termination in time regardless of capacity values.
- The final residual graph directly exposes a minimum cut, connecting this algorithm to the Max-Flow Min-Cut Theorem.
Maximum flow is found by repeatedly augmenting along paths in a residual graph until none remain — and how you choose those paths determines whether the algorithm is fast, slow, or infinite.
The idea
A flow network is a directed graph with a source , a sink , and a capacity on every edge. A flow is a function satisfying capacity constraints and flow conservation at every vertex other than and : total flow in equals total flow out. The value of a flow is the net flow leaving , and the maximum flow problem asks for a flow of maximum value. The central construct is the residual graph , which depends on the current flow . For every edge with capacity and current flow , the residual graph contains:
- a forward residual edge with residual capacity , present whenever this is positive — it represents unused capacity;
- a backward residual edge with residual capacity , present whenever this is positive — it represents the ability to cancel flow already sent from to .
An augmenting path is any directed path from to in using only edges of positive residual capacity. Its bottleneck capacity is the minimum residual capacity along the path. Pushing flow equal to the bottleneck along every edge of the path strictly increases the flow value while preserving feasibility — forward edges get more flow, backward edges get flow subtracted (i.e., some previously sent flow is rerouted elsewhere). This is the mechanism that lets Ford-Fulkerson escape locally greedy but globally suboptimal routing decisions made early on.
How it works
The method is a loop: build the residual graph, search it for any - path, augment along it, and repeat. It terminates precisely when the residual graph has no path from to — equivalently, when is unreachable from using only positive-residual edges. ``` FORD-FULKERSON(G, s, t): for each edge (u, v) in G.E: f(u, v) = 0 f(v, u) = 0 // symmetric bookkeeping, or track only forward while there exists a path p from s to t in the residual graph G_f: c_f(p) = min { c_f(u, v) : (u, v) is an edge on p } // bottleneck for each edge (u, v) on p: if (u, v) is a "forward" original edge: f(u, v) = f(u, v) + c_f(p) else: // (u, v) is a reverse of original edge (v, u) f(v, u) = f(v, u) - c_f(p) // residual capacities are implicitly updated: // c_f(u,v) = c(u,v) - f(u,v), c_f(v,u) = f(u,v) return f ``` ``` EDMONDS-KARP(G, s, t): for each edge (u, v) in G.E: f(u, v) = 0 loop: // BFS in the residual graph, restricted to positive-capacity edges find shortest path p from s to t in G_f using BFS if no such path exists: return f c_f(p) = min { c_f(u, v) : (u, v) on p } for each edge (u, v) on p: augment f along (u, v) by c_f(p) // updates both the forward residual and the paired backward residual ``` Two design choices make this precise and implementable: 1. Residual capacity bookkeeping is usually done with a paired-edge representation: every original edge with capacity is stored alongside a reverse edge with capacity initialized. Sending units of flow along decreases the residual capacity of by and increases the residual capacity of by , automatically implementing cancellation. 2. Path search can be any graph search — DFS, BFS, or something smarter. Generic Ford-Fulkerson leaves this unspecified; Edmonds-Karp nails it down to BFS, which finds a shortest (fewest-edges) augmenting path each iteration.
Complexity & correctness
Correctness (why the final flow is maximum). The proof rests on the max-flow min-cut correspondence. Define a cut as a partition of with , ; its capacity is the sum of capacities of edges from to . For any flow and any cut, the flow value equals the net flow across the cut, which is at most the cut's capacity. So max flow min cut always. When Ford-Fulkerson terminates, there is no augmenting path in , meaning is unreachable from in the residual graph. Let be the set of vertices reachable from in , and . Since no residual edge crosses from to :
- every original edge from to must be fully saturated (), otherwise a positive-residual forward edge would exist and would be reachable;
- every original edge from to must carry zero flow (), otherwise a positive-residual backward edge would put in .
The flow value therefore equals exactly the capacity of cut . Combined with the general inequality (flow value any cut capacity), this flow value is the maximum possible, and is a minimum cut. This is the constructive core of the Max-Flow Min-Cut Theorem: Ford-Fulkerson doesn't just compute max flow, it exhibits a matching min cut as a certificate of optimality.
Termination and pseudo-polynomial time. Each augmentation strictly increases the flow value by at least 1 (assuming integer capacities), and the flow value is bounded above by the finite min cut capacity, so the loop must terminate. If is the max flow value, at most augmentations occur, each requiring work to find a path (DFS/BFS) and to augment, giving total time. This is pseudo-polynomial: it depends on the numeric magnitude of capacities, not just the graph size, and can be exponential in the input's bit-length if capacities are large and paths are chosen adversarially.
Non-termination with irrational capacities. If capacities are irrational and augmenting paths are chosen adversarially, Ford-Fulkerson can run forever, converging to a value strictly less than the true max flow — a classical counterexample (due to Ford and Fulkerson themselves, later elaborated) uses the golden ratio to construct an infinite non-terminating sequence of shrinking augmentations. This is why the method, left unspecified, is not an algorithm in the strict sense.
Edmonds-Karp: BFS fixes everything. Edmonds-Karp always augments along a shortest - path in the residual graph (fewest edges, found by BFS, each edge weight treated as 1). Two facts drive the complexity proof: 1. The shortest-path distance from to any vertex in the residual graph is monotonically non-decreasing over the course of the algorithm. Intuitively, augmenting can only remove edges (saturating them) and add reverse edges that point "backward," which cannot shorten future forward paths. 2. Each edge can be the bottleneck (the unique saturating edge) of an augmenting path at most times. When an edge is the bottleneck, it disappears from the residual graph; for it to reappear, flow must be pushed back along , which requires to precede on a later shortest path — and the distance argument shows the shortest-path length to must have strictly increased by at least 2 between consecutive times is a bottleneck. Since shortest-path length is bounded by , this can happen at most times per edge. With edges each saturating times, there are augmentations total. Each augmentation costs for the BFS. Total time:
This bound is independent of capacity values — a genuinely polynomial algorithm, unlike the generic method.
Space. Both variants use space for the graph and residual capacities, plus for BFS/DFS bookkeeping — no more than the input itself requires.
Honest tradeoffs. Edmonds-Karp's is often outperformed in practice by other refinements — Dinic's algorithm achieves using blocking flows and level graphs, and push-relabel variants achieve even better bounds on dense graphs — but Edmonds-Karp remains the simplest provably polynomial instantiation of the Ford-Fulkerson idea and the natural stepping stone toward those algorithms.
Worked example
Consider this small network (capacities shown), computing max flow from to :
| Edge | Capacity |
|---|---|
| s → a | 10 |
| s → b | 10 |
| a → b | 2 |
| a → t | 4 |
| b → t | 9 |
Run Edmonds-Karp (BFS picks shortest augmenting paths):
| Iteration | BFS path found | Bottleneck | Flow value after | Notes |
|---|---|---|---|---|
| 1 | s → a → t | min(10, 4) = 4 | 4 | a→t now saturated |
| 2 | s → b → t | min(10, 9) = 9 | 13 | b→t now saturated |
| 3 | s → a → b → t | need residual on b→t: none forward, but check residual of a→b, and reverse on b→t? | — | b→t saturated forward; reverse edge t→b has capacity 9 but doesn't help toward t |
| 3′ | s → a → b → t is invalid (b→t forward is 0); try s → a → ... | no path with positive residual reaches t | — | search terminates |
Let's be precise about iteration 3. After iterations 1–2, residual capacities are:
- ,
- ,
- (untouched),
- ,
- ,
BFS from : reachable via (residual 6) and (residual 1). From , can reach (residual 2) — but not (residual 0). From , can reach... nothing new toward (residual 0). So is unreachable. The algorithm terminates with flow value . Verify optimality via the cut exposed by the final BFS reachable set , . Capacity of this cut is , exactly matching the flow value — confirming, by the max-flow min-cut argument, that 13 is indeed optimal, and no cleverer path selection could have done better. Compare with what a badly chosen DFS-based generic Ford-Fulkerson might do on a network with capacities 1000, 1000, 1 in a specific gadget (the classic pathological example): choosing augmenting paths through the capacity-1 edge repeatedly can force 2000 augmentations of size 1 each, despite the answer being reachable in 2 augmentations of size 1000. This is precisely the failure mode Edmonds-Karp's BFS rule eliminates, since shortest paths never route through unnecessarily long detours when a direct saturating path is available.
Common pitfalls & traps
| Pitfall | Why it happens | Fix |
|---|---|---|
| Forgetting reverse residual edges | Treating the graph as static, only decrementing forward capacity | Always maintain paired forward/backward residual edges; initialize reverse capacity to 0 |
| Using DFS with arbitrary tie-breaking | DFS can pick long, capacity-poor paths repeatedly | Use BFS (Edmonds-Karp) for guaranteed polynomial time, or scale capacities |
| Assuming termination with real-valued capacities | Generic method with adversarial path choice can loop forever on irrational inputs | Use integer capacities, or a strongly-polynomial variant (Dinic's, BFS-based) |
| Confusing flow value with edge flow sum | Summing all edge flows instead of net flow out of | Flow value = net flow leaving (or entering ), not total flow on all edges |
| Ignoring parallel edges / self-loops | Residual graph construction assumes simple capacity semantics | Merge parallel edges' capacities or handle them explicitly in the residual graph |
| Stopping too early | Treating "no path found by one particular search" as "no path exists" | Confirm true unreachability (BFS/DFS from over all positive-residual edges) before halting |
Pioneers & history
The method is named for L. R. Ford Jr. and D. R. Fulkerson, whose 1956 RAND Corporation report on maximum flow in networks — motivated in part by Cold War-era transportation and logistics problems — introduced both the augmenting-path method and the max-flow min-cut theorem it certifies. Their monograph Flows in Networks (1962) became the founding text of network flow theory.
Origins · 1 minLester Randolph Ford Jr. and how this was discovered
Ford, together with Fulkerson, formalized the maximum flow problem and proved the max-flow min-cut theorem while working at RAND on problems related to Soviet railway network capacity — a Cold War logistics question repurposed into one of the deepest results in combinatorial optimization.
Where this matters
Maximum flow computations underlie network routing and capacity planning in telecommunications, where link bandwidths act as capacities and traffic engineering seeks maximum throughput or robust cut structures. In computer vision, image segmentation via graph cuts (foreground/background separation) is solved as a min-cut/max-flow problem on a pixel-adjacency graph, with Ford-Fulkerson-style augmenting-path solvers (and specialized variants) at the core of tools used in medical imaging and photo editing software.
Bipartite matching — assigning workers to jobs, students to schools, or kidneys to transplant recipients — reduces directly to max flow with unit capacities, foreshadowing Bipartite Matching via Augmenting Paths, where each augmentation corresponds to finding one more compatible match. Airline crew scheduling and transportation logistics, the original motivating domain, still use flow-based formulations for capacity-constrained routing. Compiler and hardware design tools use min-cut computations (the dual output of Ford-Fulkerson) for circuit partitioning, minimizing the wires crossing a boundary. Even project selection and baseball elimination puzzles in combinatorial optimization courses are canonical max-flow reductions taught immediately after this method, building directly on the Max-Flow Min-Cut Theorem this article derives.
Ask the tutor: How does Dinic's algorithm use level graphs and blocking flows to beat Edmonds-Karp's running time?
Is Ford-Fulkerson an algorithm or a method — and why does the distinction matter?
It is called a method because it leaves one crucial decision unspecified: which augmenting path to use at each step. This isn't a pedantic distinction — the choice determines whether the procedure is fast, slow, or infinite. Generic Ford-Fulkerson with arbitrary path selection can require a number of iterations proportional to the numeric value of the max flow (pseudo-polynomial time), and with irrational capacities can fail to terminate entirely. Only once you fix a specific path-selection rule — BFS shortest paths (Edmonds-Karp), maximum bottleneck capacity (capacity scaling), or blocking flows (Dinic's) — does it become a fully specified algorithm with a provable complexity bound. This article treats Edmonds-Karp as the canonical, well-behaved instantiation.
Why does augmenting along a path always preserve flow feasibility?
Feasibility requires two things: capacity constraints and flow conservation. Augmenting by the bottleneck amount never exceeds any edge's residual capacity, since the bottleneck is defined as the minimum residual capacity along the path — so capacity constraints hold by construction. Conservation holds because every intermediate vertex on the path receives exactly as much extra flow in as it sends out (the same augmentation amount passes through), so the net flow at each intermediate vertex is unchanged. Only (net outflow increases) and (net inflow increases) see their totals change, which is exactly the desired effect of increasing the flow value.
How does the residual graph handle undirected edges or edges in both directions between two vertices?
An undirected edge with capacity is typically modeled as two directed edges, and , each with capacity , allowing flow in either direction (but not simultaneously exceeding net in one direction under standard formulations). If the original graph already has both and as directed edges with their own capacities, care must be taken in the residual graph representation — often by using four "edges" (two originals, two reversals) or by tracking net flow with a single combined variable. Implementations typically use an adjacency-list-of-edge-objects representation, where each edge object stores its capacity, current flow, and a pointer to its paired reverse edge, avoiding ambiguity.
What is the relationship between Ford-Fulkerson and the Max-Flow Min-Cut Theorem?
Ford-Fulkerson's termination condition is the constructive proof of the theorem. When no augmenting path remains, the set of vertices reachable from in the residual graph defines a cut whose capacity exactly equals the current flow value. Since flow value never exceeds any cut's capacity (a general fact independent of the algorithm), matching a specific cut's capacity certifies optimality. So running Ford-Fulkerson to completion doesn't just compute a number — it exhibits a min cut as a certificate, which is why the theorem and the method are historically and logically inseparable.
Why is Edmonds-Karp's O(VE^2) bound considered good, given that faster algorithms exist?
O(VE^2) is polynomial and capacity-independent, a qualitative leap over the pseudo-polynomial generic method — this was itself a notable result in 1972. It is not the fastest known: Dinic's algorithm improves this to O(V^2E) using blocking flows over level graphs, and push-relabel methods and more recent near-linear-time algorithms (for various capacity/graph regimes) do better still on large or dense graphs. Edmonds-Karp remains pedagogically central because its proof technique — the monotonic non-decrease of shortest-path distances — is the direct ancestor of the level-graph arguments used in faster algorithms, making it the natural first stop before those more advanced methods.
Can Ford-Fulkerson handle graphs with cycles or multiple paths between the same pair of vertices?
Yes — the method makes no assumption of acyclicity. Cycles in the original graph simply become part of the residual graph, and BFS or DFS path-finding naturally avoids revisiting vertices within a single augmenting path search (standard graph search algorithms track visited vertices). If multiple parallel edges exist between two vertices, they should be either merged into a single edge with combined capacity or tracked as distinct residual edges, but the algorithm's correctness argument via cuts and conservation is unaffected either way, since it depends only on capacity and conservation constraints, not on the graph being a DAG.
Does the choice of augmenting path affect the final max flow value?
No — the maximum flow value is unique regardless of which sequence of augmenting paths is chosen, as long as the algorithm runs until no augmenting path remains (this follows from the max-flow min-cut argument, which applies to any terminating execution). However, the specific flow assignment achieving that value, and especially the specific minimum cut exposed at termination, can differ between runs if multiple minimum cuts exist. What path selection does affect is purely the running time: bad choices can blow up the number of iterations enormously, which is exactly the problem Edmonds-Karp's BFS rule fixes.