Why “Cheapest” Changes the Flow Problem
A maximum-flow algorithm treats all feasible routes as interchangeable: if two routes can each carry one unit, either is equally useful. Real systems do not work that way. One shipping lane may be slower, one worker–shift pairing may be less desirable, and one data route may consume more bandwidth. Minimum-cost maximum flow (MCMF) keeps the capacity logic of maximum flow while attaching a price to every unit that crosses an edge.
How the idea evolved
The Optimization Model
For every directed edge $(u,v)$, let $c(u,v)$ be its capacity, $w(u,v)$ its cost per unit, and $f(u,v)$ the chosen flow. A legal solution satisfies two kinds of constraints:
Capacity
No edge carries a negative amount or more than it can hold: $0 \le f(u,v) \le c(u,v)$.
Conservation
Except at source $s$ and sink $t$, every vertex sends out exactly what it receives.
The value $|f|$ is the net amount leaving the source. MCMF uses a lexicographic objective: first maximize $|f|$; among all maximum flows, choose one with minimum total cost:
Two closely related questions
Minimum-cost maximum flow: send every unit the network can possibly carry, then minimize its cost.
Minimum-cost flow of demand $D$: stop after exactly $D$ units. This fixed-demand form is often the one used in production planning.
Residual Edges Are an Undo Button
The residual network records what the algorithm may change next. If an original edge has capacity $c$, cost $w$, and currently carries flow $f$, its residual representation contains:
| Residual edge | Residual capacity | Residual cost | Meaning |
|---|---|---|---|
| Forward $u \to v$ | $c-f$ | $w$ | Send more flow along the original edge. |
| Reverse $v \to u$ | $f$ | $-w$ | Cancel flow that was sent earlier and refund its cost. |
The key global insight
A locally cheapest first route need not belong to the cheapest final collection of routes. Negative-cost reverse edges let later augmentations repair earlier choices, so the algorithm is not trapped by its first decision.
Successive Shortest Augmenting Paths
The successive shortest augmenting path method turns optimization into repetition. At each round it asks: “Given everything I can still add or undo, what is the cheapest way to send the next batch from $s$ to $t$?”
flowchart LR
S[Residual network] --> P[Cheapest s-to-t path]
P --> B[Path bottleneck]
B --> U[Push and update]
U --> S- Build or maintain the residual graph.
- Find a minimum-cost residual path from $s$ to $t$.
- Let $\Delta$ be the smallest residual capacity on that path.
- Push $\Delta$ units, subtracting it from forward residual capacities and adding it to reverse capacities.
- Stop when $t$ is unreachable or when the requested demand has been delivered.
The bottleneck matters because one shortest-path search can often ship several units. That makes the number of rounds depend on the structure of the capacities, not simply on the number of edges.
A Worked Network, One Augmentation at a Time
Edge labels below use capacity · cost per unit. The highlighted route is the cheapest initial path: $s \to A \to B \to t$, with unit cost $1+0+1=2$ and bottleneck $1$.
| Round | Cheapest residual path | Unit cost | Push | Total flow | Total cost |
|---|---|---|---|---|---|
| 1 | $s \to A \to B \to t$ | $2$ | $1$ | $1$ | $2$ |
| 2 | $s \to B \to t$ | $3$ | $1$ | $2$ | $5$ |
| 3 | $s \to A \to t$ | $4$ | $1$ | $3$ | $9$ |
After round 3, all three units of source capacity are used, so the maximum flow is $3$. The minimum cost among flows of that value is $9$. Notice the accounting pattern: each row adds push × unit cost to the running total.
Check your intuition
Suppose the cost of $A \to t$ falls from $3$ to $0$. Which path becomes cheapest first, and what is the new minimum cost for three units?
Hint: compare the three useful route costs before simulating. Answer: $s \to A \to t$ costs $1$, and the final cost becomes $6$.
Potentials Make Dijkstra Legal Again
Reverse edges can have negative cost, and ordinary Dijkstra is not correct on graphs with negative edge weights. Potentials repair that problem without changing which $s$-$t$ path is cheapest.
Maintain a potential $\pi(v)$ for each vertex and replace each residual cost with a reduced cost:
Every $s$-$t$ path gains the same telescoping offset, $\pi(s)-\pi(t)$. Therefore, comparing reduced path costs gives the same ordering as comparing original path costs.
1. Initialize
Use $\pi(v)=0$ when original costs are nonnegative. Otherwise compute initial shortest distances with Bellman–Ford.
2. Search
Run Dijkstra using $\widehat{w}$ on residual edges with positive capacity.
3. Update
For every reached vertex, set $\pi(v) \leftarrow \pi(v)+d(v)$.
Why does the update keep reduced costs nonnegative? Dijkstra’s distances obey $d(v) \le d(u)+\widehat{w}(u,v)$. Rearranging gives $\widehat{w}(u,v)+d(u)-d(v) \ge 0$, which is exactly the new reduced cost.
What potentials really are
A potential is a bookkeeping price attached to a vertex. It absorbs the negative reverse-edge costs into vertex offsets, leaving nonnegative edge weights for the next Dijkstra run while preserving the true path comparison.
Why the Method Works
The full proof is a primal–dual argument, but its core can be understood through three invariants:
Feasibility
Pushing no more than the bottleneck preserves capacities; augmenting along a complete $s$-$t$ path preserves conservation.
Cheapest increment
A shortest residual path is the least expensive legal way to increase the current flow value.
No cheaper repair
At optimum, the residual graph contains no negative-cost cycle that could reroute flow and lower cost without changing its value.
Reverse edges are what connect the last two ideas. Any alternative flow of the same value differs from the current flow by residual cycles. If none of those cycles has negative cost, no alternative can be cheaper. When no residual $s$-$t$ path remains, the flow is also maximum.
Implementation: Separate the Four Responsibilities
A robust solver is easier to reason about when four jobs stay distinct: edge insertion creates paired forward/reverse edges, shortest-path search records a parent edge for every vertex, augmentation updates both residual directions, and accounting updates total flow and cost.
What the code widget demonstrates
The tabs below isolate the shortest-path kernel on nonnegative costs. A full MCMF solver must additionally store reverse-edge indices, maintain residual capacities, reconstruct the chosen path, apply the bottleneck, and use potentials when negative residual costs exist.
| Edge field | Why it exists |
|---|---|
to | The endpoint reached by this residual edge. |
rev | The index of its paired reverse edge, enabling $O(1)$ updates. |
cap | Current residual capacity, not the original capacity. |
cost | Original cost for a forward edge and its negation for the reverse edge. |
In each round, save the exact parent edge, not merely the parent vertex; parallel edges may connect the same two vertices. Reconstruct the path from $t$ to $s$, find its minimum residual capacity, then update every chosen edge and its paired reverse edge.
Implementation checklist
- Create the reverse edge at the same time as the forward edge.
- Use a wide integer type for distances and total cost; the product
flow × edge_costcan overflow before the final sum does. - Skip residual edges whose capacity is zero.
- Update potentials only for vertices reached by the current shortest-path run.
- Return both achieved flow and total cost; a fixed demand may be infeasible.
Where the Model Pays Off
MCMF is most natural when resources are divisible into units, constraints can be expressed as edge capacities, and preferences add linearly as per-unit costs.
Warehouse to Store
Supply edges limit inventory, lane capacities limit transport, and costs combine freight, handling, and lateness penalties.
Worker to Job
Unit capacities enforce one-to-one choices; the worker–job edge cost represents preference, travel, or expected effort.
Demand Across Time
Time-expanded layers model inventory carry-over, machine availability, and the cost of postponing work.
Ads or Compute
Capacity limits protect budgets and resources while costs encode mismatch, latency, or opportunity cost.
Assignment as a flow network
Create edges $s \to$ worker with capacity $1$ and cost $0$, worker $\to$ job with capacity $1$ and a preference cost, and job $\to t$ with capacity $1$ and cost $0$. Maximum flow assigns as many workers as possible; minimum cost chooses the best available pairing among those maximum assignments. This construction also explains why the Hungarian algorithm is a specialized alternative for balanced one-to-one assignment.
Complexity and Limits
Let $A$ be the number of augmentations. With potentials and a binary-heap Dijkstra, the main loop costs:
If capacities are integers, every augmentation sends at least one unit, so $A \le F$ for final flow value $F$. This gives the familiar worst-case bound $O(FE\log V)$, plus up to $O(VE)$ for a Bellman–Ford initialization when negative original costs exist. Memory usage is $O(V+E)$ after including reverse edges.
Where the simple method strains
- Huge numeric capacities: the $F$-dependent bound is pseudo-polynomial even if each round usually pushes more than one unit.
- Floating-point costs: equality and reduced-cost comparisons become fragile; scale to integers when the domain allows it.
- Negative cycles: they require careful modeling and may signal an unbounded fixed-flow formulation when unlimited circulation is possible.
- Extra business rules: logical choices, nonlinear discounts, and cross-period coupling may require linear or mixed-integer programming instead.
Choosing the Right Flow Tool
| Problem shape | Good starting point | Reason |
|---|---|---|
| Only maximize throughput | Dinic’s algorithm | Avoids cost machinery you do not need. |
| Sparse network, moderate integral flow, linear costs | Successive shortest paths + potentials | Direct, understandable, and usually practical. |
| Balanced one-to-one assignment | Hungarian algorithm | Specialized $O(n^3)$ structure. |
| Very large costed-flow instances | Cost scaling or network simplex | Better scaling than one augmentation at a time. |
| Side constraints or discrete business logic | LP/MIP solver | Expresses rules that do not fit ordinary flow conservation. |
Mental model to keep
MCMF repeatedly buys the cheapest remaining unit of $s$-$t$ flow. Residual reverse edges let it return an earlier purchase; potentials change the price labels so Dijkstra can shop safely; the process ends when the demand is met or no route remains.