All-Pairs and Negative Weights
Dijkstra's greedy schedule breaks the moment an edge goes negative. We give it up for dynamic programming: Bellman-Ford derived as a DP over edge budgets, with its negative-cycle detector, and Floyd-Warshall computing the distance between every pair of vertices via a DP over which vertices a path may pass through.
╌╌╌╌
This builds on Shortest Paths, which developed the relaxation primitive and Dijkstra's greedy algorithm for non-negative weights. Dijkstra's whole correctness argument leaned on non-negativity in one place — extending a path never lowers its cost
— and one negative edge breaks it. Handling negative weights means abandoning the greedy schedule for dynamic programming, which is where we pick up.
Bellman-Ford as a dynamic program
Dijkstra breaks when edges can be negative — its greedy finalization assumes
a finalized estimate can never improve, which negative edges violate.
trades speed for generality. It is best derived
not as relax everything repeatedly
but as a genuine
dynamic program. That framing is
worth keeping, because it explains where the comes from.
The subproblem. Bound the number of edges a walk may use. For each vertex and each budget , define
The full answer we want is for , since (as we prove below) shortest paths never need more than edges.
The recurrence. A cheapest walk to using at most edges either uses at most edges already, or it takes one final edge after a cheapest -edge walk to . Minimizing over both:
with base cases and for . This is relaxation in another guise: filling row of the table from row is one full pass that relaxes every edge. The tabular form makes the layering explicit, with row holding the best walk of length :
- 1; for
- 2for to doone pass over all edges per row
- 3foreach vertex do
- 4inherit: no extra edge
- 5foreach edge do
- 6if then
- 7
- 8
- 9return and
Why stop after rounds? This is the theorem that licenses the whole algorithm.
So the rows of the DP stop changing by row .
A second, sharper argument gives the same bound, phrased directly in terms of relaxation.1 It explains not just that rounds suffice but which vertices are already correct after each round.
Round of Bellman-Ford relaxes every edge, in particular the -th edge of any shortest path you care to name, and it does so after round handled the -st. So after round , every vertex whose shortest path uses at most edges holds its exact distance, and since no shortest path needs more than edges, rounds settle every vertex. The correct region grows along every shortest path by at least one edge per round:
Saving space. The recurrence only ever reads row , so we collapse the table to a single 1-D array updated in place, recovering the familiar form of Bellman-Ford as rounds of relaxing every edge. (In-place updates can only make estimates better than the strict row-by-row schedule; the path-relaxation lemma tolerates the extra interleaved relaxations.) Negative edges are fine; only a negative cycle breaks the theorem.
- 1foreach vertex do
- 2
- 3
- 4
- 5for to doV-1 full-relaxation rounds
- 6foreach edge do
- 7call
- 8foreach edge doextra pass: detect neg cycle
- 9if then
- 10return falseneg cycle reachable from s
- 11return true
Detecting negative cycles. After rounds, if any edge can still be
relaxed, some walk was improved using edges — only possible if a negative
cycle lets the cost descend without bound. So one extra pass serves as the
test: relax everything once more, and any successful relaxation certifies a
negative cycle reachable from (where cheapest cost to reach a vertex
is no
longer even well-defined).2 The extra pass is a decision procedure, and it is both
sound and complete: a relaxation can
succeed only when a reachable negative cycle exists (soundness, no false alarm), and
any such cycle forces some edge to relax on that pass (completeness, none is missed).
Dijkstra entirely lacks that capability. The
cost is : passes, each relaxing all
edges.
Laid out as the DP table , the layering is plain: row holds the cheapest walk of at most edges, each row computed from the one above by a single full pass of relaxation. The entries that improved on each row are shaded; the table stops changing after row , well within the bound:
Floyd-Warshall: all pairs at once
Sometimes we want for every pair of vertices, a full distance matrix. Running Bellman-Ford from each source costs , up to on dense graphs, but does better with a dynamic program parameterized not by edge count but by which vertices a path is allowed to pass through.
The recurrence lifts to by a case split that is exhaustive by construction: a shortest path counted by either uses vertex as an intermediate or it does not, and there is no third possibility. If it does not, its intermediates already lie in and it is counted by . If it does, then (assuming no negative cycles, we may take the path simple, so appears exactly once) splits the path into an half and a half, neither of which contains in its interior. Both halves have intermediates in , and by optimal substructure each half is a shortest path of its own class, so their costs are exactly and . Taking the better case:
Induction on turns this into correctness: is right by definition, and if holds every -limited distance, the case split shows the recurrence computes every -limited one. After round , no restriction remains.
Consider one round of the recurrence. Starting from — direct edges only — and admitting intermediates from produces : the entry drops from to via , and the once-unreachable become finite by routing through vertex then . The five matrices below trace one round per permitted intermediate; the entries that improved in each round are shaded:
Three nested loops over , , evaluate this recurrence directly: the outer loop admits one intermediate vertex per round (exactly the five matrices above), and the inner two relax every pair against a route through it.
- 1: edge weight; on the diagonal, else
- 2for to doadmit vertex as an intermediate
- 3for to do
- 4for to do
- 5if thenrouting through is shorter
- 6
- 7return
The pseudocode quietly drops the superscripts and updates one matrix in place,
and this needs a word of justification: during round , could an entry
or that the recurrence reads have already been overwritten
with a round- value? It could, but harmlessly, because row and column
do not change during round :
, since (and whenever no negative cycle
exists). Reading new
values is the same as reading old ones, so one
matrix suffices.
Running time. The algebra is the shortest of the lesson: three nested loops of iterations each, with a constant-time comparison in the body: time and space. No priority queue, no per-edge bookkeeping: compact, cache-friendly, and a clean win on dense graphs.3 It handles negative edges, and a negative entry on the diagonal () flags a negative cycle through . For sparse graphs with non-negative weights, running Dijkstra from every source costs , which beats when ; Floyd-Warshall wins on dense inputs and on any input where its tiny constant factor and trivial implementation matter more than asymptotics.
Choosing an algorithm
| Algorithm | Solves | Negative edges? | Time |
|---|---|---|---|
| BFS | SSSP, unweighted | n/a | |
| DAG relaxation | SSSP on a DAG | yes | |
| SSSP | no | ||
| SSSP, + cycle detection | yes | ||
| all-pairs | yes |
The decision tree is short: unweighted, use BFS; a DAG, relax in topological order; non-negative weights, use Dijkstra (the fastest for one source); negative edges possible, use Bellman-Ford and let it detect negative cycles; every pair at once, use Floyd-Warshall on dense graphs, or repeated Dijkstra () when the graph is sparse and the weights non-negative. All five are disciplined applications of the same primitive; they differ only in which edges they relax, and in what order.
Sparse all-pairs and what negative cycles buy you
Johnson's algorithm. Floyd-Warshall's is fine on dense graphs but wasteful on sparse ones. Johnson's algorithm computes all-pairs shortest paths in — the cost of Dijkstra runs — while still tolerating negative edges.4 It uses a reweighting that removes the negatives without changing which paths are shortest. Add a dummy vertex with a zero-weight edge to every vertex, run Bellman-Ford once from to get a potential , then reweight each edge to
The triangle inequality makes every , and the terms telescope along any path, so a path's reweighted length differs from its true length by the constant — same ordering, same shortest paths. Now run Dijkstra from every source on the non-negative , and undo the shift. One Bellman-Ford pass establishes non-negativity; Dijkstra passes finish the job. (This is the same potential trick that underlies A* from the previous lesson.)
SPFA and the practical Bellman-Ford. In practice, few graphs force all Bellman-Ford rounds. The shortest-path faster algorithm
keeps a queue of vertices whose estimate just improved and only relaxes out of those, often finishing in far fewer than operations — though its worst case is still , so it is a constant-factor win, not an asymptotic one. Bellman-Ford also parallelizes cleanly: every edge in a round relaxes independently, which is why GPU shortest-path codes favor it over Dijkstra's inherently sequential extraction order.
What a negative cycle is worth. Bellman-Ford's negative-cycle detector is useful in its own right: some problems ask for the cycle itself. In currency arbitrage, let each currency be a vertex and each exchange rate an edge of weight . A path's total weight is of the product of rates along it, so any cycle of negative total weight is a sequence of trades that multiplies the starting sum by more than .5 Detecting arbitrage is Bellman-Ford's extra pass, and reconstructing the offending cycle from the predecessor pointers recovers the trades.
The pattern generalizes: minimum-mean-cycle, difference constraints (systems of solved by a single Bellman-Ford), and deadlock detection all reduce to shortest paths with negative edges. Whenever a problem's cost
is a sum you want to drive as low as possible around a loop, Bellman-Ford's cycle machinery is the tool.
Takeaways
- Shortest paths rest on relaxation plus two structural facts: the triangle inequality and optimal substructure.
- greedily finalizes the closest frontier vertex; the cut argument shows an extracted vertex's estimate is already exact. Correct only for non-negative weights; a single negative edge lets a cheap route arrive after its target is frozen. with a Fibonacci heap.
- is a dynamic program: = cheapest walk of edges, and one DP row = one pass of relaxing all edges. Shortest paths need edges (short-circuit any cycle), so rounds suffice; one extra round detects negative cycles. Slower at but handles negative edges.
- On a DAG, relaxing in topological order solves SSSP in .
- computes all-pairs shortest paths in via a dynamic program over intermediate vertices.
Footnotes
- CLRS, Ch. 24 & 25 — Single-Source and All-Pairs Shortest Paths — relaxation, the triangle inequality, and optimal substructure. ↩
- Erickson, Ch. 8 & 9 — Shortest Paths — Bellman-Ford's extra relaxation pass detecting a negative cycle. ↩
- Skiena, §6 — Weighted Graph Algorithms — Floyd-Warshall's all-pairs dynamic program. ↩
- Johnson, D. B. (1977),
Efficient algorithms for shortest paths in sparse networks,
Journal of the ACM 24(1), 1–13 — reweighting for all-pairs shortest paths on sparse graphs. ↩ - Cormen, Leiserson, Rivest & Stein, Introduction to Algorithms (CLRS), Problem 24-3 — currency arbitrage as a negative-weight cycle under rates. ↩
╌╌ END ╌╌