Purpose: Two related results from Goldberg and Tarjan:

  1. Max flow in push-relabel accelerated with dynamic trees;
  2. Min-cost flow by cost scaling in , where is the largest cost — the standard fast min-cost-flow algorithm.

Max flow with dynamic trees

Plain push-relabel spends on non-saturating pushes, because each one moves flow along a single edge. Dynamic trees let you maintain the current “path of pushes” as a tree and push along an entire path in :

  • link, cut, and “minimum residual capacity on the path to the root” are all amortized in a link-cut tree;
  • a non-saturating push becomes a path operation instead of edge operations, but there are far fewer of them.


Min-cost flow by cost scaling

The min-cost-flow analogue of capacity scaling, built on -optimality.

-optimal flow

With potentials , the reduced cost of an arc is . A flow is -optimal if every residual arc has . At this is exact optimality (complementary slackness).

Algorithm

  1. Start with (the maximum arc cost) and the zero flow, which is trivially -optimal.
  2. Refine: given an -optimal flow, produce an -optimal one. This is done with a push-relabel loop where “admissible” means rather than a height comparison.
  3. Halve and repeat.
  4. When , the flow is exactly optimal — because reduced costs are integers, and an violation summed around any cycle cannot reach 1.

Complexity

  • scaling phases
  • Each refine is with dynamic trees, or without
  • Total:

Min-cost flow: which algorithm?

AlgorithmTimeNotes
Cycle cancellingsimple, pseudo-polynomial
Min-mean cycle cancellingstrongly polynomial (Karp)
SSP with potentials (Johnson reweighting + Dijkstra)write this in contests
Capacity scaling SSP
Goldberg-Tarjan cost scalingthe fast general-purpose choice
Network simplexexponential worst caseoften fastest in practice

In a contest

Successive shortest paths with Johnson potentials: run Bellman-Ford once for the initial potentials (needed if there are negative costs), then repeatedly Dijkstra on reduced costs, updating potentials each round. About 80 lines and fast enough whenever the total flow is small — which it usually is, since flow value is typically in matching-style problems.

Variants / Use Cases