A directed graph G = (V, E) with two distinguished vertices and a capacity function:
A flow network is a tuple (G, s, t, c):
G = (V, E) directed graph
s ∈ V source vertex
t ∈ V sink vertex
c: E → R⁺ capacity function
Flow networks model any system where something moves through a constrained network — water in pipes, data in networks, goods through supply chains.
Every valid flow must satisfy two properties:
| Constraint | Formal | Meaning |
|---|---|---|
| Capacity | 0 ≤ f(u,v) ≤ c(u,v) | Flow on an edge cannot exceed its capacity |
| Conservation | Σ f(u,v) = Σ f(v,w) for all v ≠ s,t | Flow into a node equals flow out of that node |
The total flow leaving the source (equivalently, arriving at the sink):
|f| = Σ f(s,v) - Σ f(v,s)
= Σ f(v,t) - Σ f(t,v)
Find a flow f that maximises |f| while satisfying capacity and conservation constraints. This is a linear programming problem with efficient combinatorial solutions.
A partition of vertices into sets S and T where s ∈ S and t ∈ T. The capacity of the cut is:
c(S, T) = Σ c(u,v) for all u ∈ S, v ∈ T
Only edges crossing from S to T count — not edges from T to S.
In any flow network, the maximum flow from s to t equals the minimum capacity of any s-t cut:
max |f| = min c(S, T)
The max-flow min-cut theorem is a special case of LP strong duality. Every max-flow algorithm implicitly finds a minimum cut as well.
Given a flow f, the residual graph Gf shows remaining capacity on each edge:
Forward edge: c_f(u,v) = c(u,v) - f(u,v)
(room to push more flow)
Backward edge: c_f(v,u) = f(u,v)
(room to cancel existing flow)
A path from s to t in the residual graph Gf. The bottleneck is the minimum residual capacity along the path.
A flow f is maximum if and only if there is no augmenting path from s to t in Gf.
Backward edges are the key insight — they allow algorithms to "undo" earlier flow decisions. Without them, greedy approaches can get stuck at suboptimal solutions.
Ford-Fulkerson(G, s, t):
initialise f(u,v) = 0 for all edges
while ∃ augmenting path p in G_f:
cf(p) = min residual capacity along p
for each edge (u,v) in p:
f(u,v) += cf(p)
f(v,u) -= cf(p)
return f
O(E · |f*|) where |f*| is max flow valueWith integer capacities, a poorly chosen path strategy can require |f*| augmentations. If max flow is 2,000,000, that is 2,000,000 iterations — each augmenting by 1.
Ford-Fulkerson is a method, not an algorithm — it does not specify how to find the augmenting path. The choice of path-finding strategy determines the actual complexity.
Always choose the shortest augmenting path (fewest edges) using breadth-first search.
Edmonds-Karp(G, s, t):
initialise f = 0
while BFS finds path p from s to t in G_f:
cf(p) = bottleneck of p
augment flow along p by cf(p)
return f
| Metric | Bound |
|---|---|
| Augmentations | O(VE) |
| Each BFS | O(E) |
| Total | O(V · E²) |
O(E) augmentations, some shortest path distance increasesO(V) distance increases possible — hence O(VE) total augmentationsEdmonds-Karp is the first polynomial-time max-flow algorithm. Independent of flow value, always O(VE²).
Dinic's algorithm builds a level graph using BFS and finds blocking flows using DFS.
Dinic(G, s, t):
while BFS builds level graph L of G_f:
while ∃ blocking flow f' in L:
augment f by f'
rebuild level graph
return f
| Metric | Bound |
|---|---|
| Phases | O(V) |
| Blocking flow | O(VE) per phase |
| Total | O(V² · E) |
O(E · √V) — applies directly to bipartite matching problems
O(E · √V) — every vertex has in-degree or out-degree 1
Dinic's algorithm is strictly faster than Edmonds-Karp. The improvement comes from finding multiple augmenting paths per BFS phase using blocking flows.
s in Gfd(v) = shortest distance from s(u,v) where d(v) = d(u) + 1tA flow in the level graph such that every s-t path contains at least one saturated edge. Not necessarily a maximum flow — but simpler to find.
DFS from s:
advance along unsaturated edges
if reach t:
augment along path, retreat
if stuck at v:
delete v from level graph
retreat
O(1) amortisedO(E) advances and O(V) retreats per blocking flowThe level graph acts as a "pruned" version of the residual graph, keeping only edges that make forward progress toward the sink.
A different paradigm (Goldberg & Tarjan, 1988). Instead of finding augmenting paths, push-relabel maintains a preflow — conservation is relaxed, allowing excess at vertices.
| Concept | Description |
|---|---|
| Preflow | Flow where inflow can exceed outflow (excess allowed) |
| Excess e(v) | Σ f(u,v) - Σ f(v,w) — flow pooling at v |
| Height h(v) | Label for each vertex; s starts at |V|, t at 0 |
| Active vertex | A vertex with e(v) > 0 and v ≠ s, t |
min(e(u), cf(u,v)) flow; requires h(u) = h(v) + 1h(u) to min(h(v) + 1) over admissible neighboursPush-Relabel(G, s, t):
h(s) = |V|, saturate all edges from s
while ∃ active vertex u:
if u has admissible edge (u,v):
push(u, v)
else: relabel(u)
| Variant | Time |
|---|---|
| Generic push-relabel | O(V² · E) |
| FIFO selection | O(V³) |
| Highest-label | O(V² · √E) |
If no vertex has height h, then any vertex with height above h cannot reach the sink. Relabel all such vertices to |V| + 1 — they drain back to source.
Periodically recompute exact heights using reverse BFS from t. Dramatically reduces wasted pushes in practice.
In practice, push-relabel with highest-label selection and gap/global relabelling heuristics is the fastest max-flow algorithm for dense graphs.
Given a flow network where each edge has both a capacity and a cost per unit of flow, find a flow of value d that minimises total cost.
Minimise: Σ a(u,v) · f(u,v) over all edges
Subject to: flow conservation, capacity constraints, |f| = d
| Problem | Objective |
|---|---|
| Max flow | Maximise flow value, no costs |
| Min-cost flow | Fix flow value, minimise cost |
| Min-cost max flow | Maximise flow, break ties by min cost |
d = 1Min-cost flow is one of the most powerful network optimisation models. Many seemingly different problems reduce to it.
Repeatedly find the shortest (cheapest) augmenting path and send flow along it. Uses Bellman-Ford or Dijkstra with potentials.
while |f| < d:
find shortest path p
in G_f (by cost)
augment along p
O(d · (E + V log V)) with Dijkstra + potentials
Start with any feasible flow. Find negative-cost cycles in the residual graph and push flow around them until none remain.
O(V · E² · C · U) — pseudo-polynomial
Specialised simplex method for network flow LPs. Maintains a spanning tree basis. Strongly polynomial in practice and often the fastest.
Practical choice for large-scale problems
For competitive programming: successive shortest paths with Dijkstra + potentials (SPFA/Johnson) is the standard min-cost flow template.
Given a bipartite graph G = (L ∪ R, E), find the largest set of edges with no shared endpoints.
s connected to all vertices in L (capacity 1)t connected from all vertices in R (capacity 1)max matching = min vertex cover (bipartite only)
Specialised for bipartite matching. Uses BFS to find maximal sets of shortest augmenting paths, then DFS to augment.
Complexity: O(E · √V) — equivalent to Dinic's on unit networks.
Any bipartite matching problem can be solved as max flow. For unweighted, Hopcroft-Karp is optimal. For weighted, use the Hungarian algorithm or min-cost flow.
Weighted bipartite matching (Kuhn, 1955). Find a perfect matching in a weighted bipartite graph that minimises (or maximises) total weight.
Maintain feasible vertex labels (potentials) such that:
l(x) + l(y) ≥ w(x,y) ∀ x ∈ L, y ∈ R
The equality subgraph contains only edges where l(x) + l(y) = w(x,y). A perfect matching in the equality subgraph is optimal.
l(x) = max w(x,y) for left, l(y) = 0 for right| Implementation | Time |
|---|---|
| Naive | O(n⁴) |
| Shortest-path optimisation | O(n³) |
The Hungarian algorithm solves the assignment problem optimally. It can also be viewed as a primal-dual method for the assignment LP.
Ship goods from m suppliers to n consumers at minimum cost, respecting supply/demand.
| Component | Network model |
|---|---|
| Suppliers | Source nodes with supply si |
| Consumers | Sink nodes with demand dj |
| Routes | Edges with capacity & cost |
| Objective | Min-cost flow |
Assign n workers to n jobs, one-to-one, minimising total cost.
Special case of transportation where all supplies and demands are 1.
Solved optimally by the Hungarian algorithm in O(n³) or by min-cost flow.
The simplex method was originally developed (Dantzig, 1947) partly to solve military transportation and logistics problems — network flow was one of the first LP applications.
Partition image pixels into foreground (F) and background (B):
s = foreground label; sink t = background label(s, pixel) = likelihood pixel is foreground(pixel, t) = likelihood pixel is background(pixeli, pixelj) = smoothness penalty for different labelsThe max number of edge-disjoint paths between two nodes equals the minimum edge cut (Menger's theorem). Max flow computes this directly.
Determine if a team is mathematically eliminated from winning the league. Formulated as max-flow by Schwartz (1966).
Choose a subset of projects to maximise profit, respecting prerequisite dependencies. Equivalent to min-cut.
The power of network flow lies in modelling: once a problem is cast as a flow network, efficient algorithms immediately apply.
To limit flow through vertex v, split it into vin and vout:
Original: u → v → w
Split: u → v_in →(cap)→ v_out → w
Add a super-source S connected to all sources and a super-sink T connected from all sinks. Edge capacities encode supply/demand.
If edge (u,v) must carry at least l(u,v) flow:
l(u,v) flow on every lower-bounded edgeUndirected: replace with two directed edges, same capacity each.
Time-expanded: replicate graph for each time step. Edges across time model temporal constraints.
Mastering these transformations is the key skill for network flow in practice and competitions. The algorithm is the easy part — the modelling is the hard part.
| Algorithm | Time | Notes |
|---|---|---|
| Ford-Fulkerson | O(E·|f*|) | Pseudo-polynomial |
| Edmonds-Karp | O(V·E²) | BFS shortest path |
| Dinic's | O(V²·E) | Blocking flows |
| Push-Relabel | O(V²·E) | Generic |
| Highest-label PR | O(V²·√E) | Best practical |
| Orlin | O(VE) | Optimal dense (2013) |
| Problem | Best known |
|---|---|
| Min-cost flow | O(VE log V log(VC)) |
| Bipartite matching | O(E·√V) Hopcroft-Karp |
| Weighted matching | O(n³) Hungarian |
| General matching | O(V·E) Edmonds' blossom |
In practice, push-relabel with heuristics dominates for large dense graphs. Dinic's is preferred for sparse graphs and competitive programming.
O(V²E) and is optimal for unit-capacity graphs at O(E√V)O(n³)| Source | Description |
|---|---|
| CLRS | Introduction to Algorithms, Ch. 24-26 |
| Ahuja et al. | Network Flows — the definitive reference |
| Kleinberg & Tardos | Algorithm Design, Ch. 7-8 |
| Schrijver | Combinatorial Optimization |
| Jeff Erickson | Free textbook — excellent flow chapters |
| CP-Algorithms | Implementation-focused flow tutorials |