Wait, What?
The shortest path from one place to every other place is not the same problem as knowing the shortest path between every possible pair.
That difference changes the shape of the algorithm. A single-source problem can expand from one starting point. An all-pairs shortest-path problem asks for an entire distance matrix, and the best method depends strongly on graph density, edge signs, memory constraints and whether the graph changes while we are computing.
This Learning Hall article owns the learning of all-pairs shortest paths. The existing Graph Algorithms article owns graph representation, BFS, DFS and introductory shortest-path selection; Heuristic Search owns A*; and Minimum-Cost Flow owns residual-network optimization. General retrieval and transfer remain MindOS jobs; calibration remains a Bolt job; study-tool execution remains a Student/Studying Interface job.
Quick Answer
Learn all-pairs shortest paths through the route single-source baseline → distance matrix → repeated BFS/Dijkstra → negative edges → Floyd–Warshall dynamic program → intermediate-vertex invariant → path reconstruction → negative-cycle detection → Johnson reweighting → Bellman–Ford potentials → repeated Dijkstra → sparse-versus-dense choice → numerical safety → cache and blocking → parallel execution → verification. A beginner should be able to update a small Floyd–Warshall table. A professional should be able to choose the right family for the graph, defend its assumptions, reconstruct paths correctly, and engineer memory and performance for real workloads.
1. Define the Output Before the Algorithm
The all-pairs shortest-path problem asks for the shortest distance from every vertex u to every vertex v. The natural output is an n × n distance matrix. Some applications also need the actual routes, which means storing predecessor or next-hop information as well as distances.
2. Start With Repeated Single-Source Search
The simplest idea is often the right starting point: solve a single-source shortest-path problem from every vertex. For unweighted graphs that can mean repeated BFS. For non-negative weighted graphs it can mean repeated Dijkstra. This baseline gives learners something concrete against which specialized all-pairs methods can be compared.
3. Graph Density Changes the Decision
A graph with only a few edges per vertex behaves differently from one where a large fraction of vertex pairs are directly connected. Sparse graphs reward adjacency-list methods. Dense graphs make an n × n matrix less wasteful and can favour cubic matrix-style dynamic programming. “Which algorithm is faster?” is incomplete without asking what the graph looks like.
4. Negative Edges Are Not Automatically a Problem
A negative edge can be perfectly meaningful: a rebate, energy recovery or accounting credit can reduce total path cost. The real problem is a reachable negative cycle. If a route can circle repeatedly and make total cost smaller without bound, then a finite shortest path is not defined for affected pairs.
5. Floyd–Warshall Reframes the Problem
Instead of asking which edge comes last, Floyd–Warshall asks which intermediate vertices are allowed. Number the vertices. Let D[i][j] represent the best distance from i to j using only a permitted prefix of vertices as intermediates. At each stage, a new vertex k is either unnecessary or useful as a bridge.
6. The Core Recurrence Is a Choice
For every pair i, j, compare the current route with a route that goes through k: D[i][j] = min(D[i][j], D[i][k] + D[k][j]). That one line is simple only after the state meaning is understood. The proof depends on whether an optimal route uses k as an intermediate.
7. Learn the Intermediate-Vertex Invariant
After processing intermediate vertices 1..k, every matrix entry is the shortest path whose internal vertices are drawn only from that set. Before moving to k+1, this statement must already be true. This is the invariant that turns three nested loops into a correctness argument.
8. Initialize the Matrix Carefully
D[i][i] = 0unless the problem defines otherwise.- If there is an edge from i to j, initialize with its weight.
- If there is no known route, initialize with infinity.
- If parallel edges exist, keep the smallest direct weight.
Many incorrect implementations fail before the recurrence begins because their base matrix does not correctly represent “no intermediate vertices yet.”
9. Floyd–Warshall Is Cubic Time and Quadratic Space
The standard in-place implementation performs Θ(V3) update checks and stores Θ(V2) distances. MIT’s algorithms material presents Floyd–Warshall as a dynamic program with one constant-work update for each triple of vertices: MIT 6.006 Lecture 17.
10. Negative Cycles Leave a Diagonal Signal
After Floyd–Warshall, if some D[v][v] < 0, then a negative cycle is reachable from v back to itself. That does not mean every pair in the graph is invalid. A professional implementation must decide whether it merely reports the cycle or marks all source–destination pairs whose optimum is unbounded because they can reach and leave that cycle.
11. Path Reconstruction Needs More Than Distances
A distance matrix answers “how short?” but not “which path?” Maintain a predecessor or next-hop matrix whenever an update improves D[i][j]. Then reconstruct the route by following stored choices. Test this separately because a correct distance table can coexist with broken path reconstruction.
12. Johnson’s Algorithm Targets Sparse Weighted Graphs
Johnson’s algorithm keeps the sparse adjacency-list advantage while handling negative edges, provided there are no negative cycles. It does this by transforming edge weights so that Dijkstra becomes legal without changing which paths are shortest in the original graph.
13. Reweighting Is the Key Idea
Johnson computes a potential h(v) for each vertex and defines a new edge weight w'(u,v) = w(u,v) + h(u) - h(v). Along a complete path, the internal potential terms telescope. Every path from the same source to the same destination changes by the same amount, so their ordering by total cost is preserved.
14. Bellman–Ford Produces the Potentials
Add a new super-source with zero-weight edges to every original vertex, then run Bellman–Ford. If it detects a negative cycle, Johnson stops. Otherwise the resulting shortest distances from the super-source become the potentials used for reweighting.
15. Reweighted Edges Become Non-Negative
The Bellman–Ford distances satisfy the shortest-path triangle inequality h(v) ≤ h(u) + w(u,v). Rearranging gives w(u,v) + h(u) - h(v) ≥ 0. That is the proof step that authorizes Dijkstra on the transformed graph.
16. Run Dijkstra From Every Vertex
After reweighting, run Dijkstra from each original source. Convert each transformed distance back to the original scale using the same potentials. MIT 6.006 treats Johnson’s method explicitly as the sparse-graph all-pairs route: MIT 6.006 Lecture 14: APSP and Johnson.
17. Dense Versus Sparse Is a Workload Question
Floyd–Warshall is simple, regular and attractive for dense graphs. Johnson is often preferable for sparse graphs, especially when adjacency lists and efficient priority queues keep repeated Dijkstra cheap. Boost.Graph makes the same engineering distinction in its Johnson and Floyd–Warshall documentation.
18. Do Not Ignore Constant Factors
A cubic algorithm with tight loops over contiguous matrices can outperform a theoretically better sparse method at moderate sizes. Priority-queue allocations, cache misses and pointer-heavy adjacency structures matter. Asymptotic analysis narrows the candidates; measurement on representative graphs chooses between close contenders.
19. Blocking Can Change Floyd–Warshall’s Practical Speed
The standard triple loop repeatedly revisits a large matrix. Blocked variants process tiles that fit better in cache, reducing memory traffic. Research on blocked all-pairs shortest paths has demonstrated substantial practical speedups without changing the underlying mathematical recurrence.
20. Loop Order Is Not Arbitrary
The intermediate-vertex dimension must remain the outer logical progression for the standard in-place recurrence. Reordering loops carelessly can violate the invariant and mix states from the wrong stage. Performance tuning is valid only when it preserves the dependency structure.
21. Numerical Representation Can Break a Correct Algorithm
Adding a large finite value to “infinity” can overflow fixed-width integers. Floating-point sums can accumulate rounding error. Princeton’s Floyd–Warshall implementation documentation explicitly discusses arithmetic assumptions and overflow boundaries. Guard additions, choose numeric types deliberately, and test weights near limits: Princeton Algorithms — FloydWarshall.
22. Parallelism Depends on the Dependency Structure
For a fixed intermediate vertex k, many i,j updates can be parallelized once the needed row and column values are stable. Blocked CPU and GPU implementations exploit this structure. Repeated single-source runs are also naturally parallel across sources if memory bandwidth permits.
23. Dynamic Graphs Change the Job
If edges change continually, recomputing an entire all-pairs table after every update may be wasteful. That problem belongs to dynamic graph algorithms, which already have their own Learning Hall article. Keep static all-pairs reasoning separate from incremental update machinery.
24. Build a Differential Test Oracle
For small graphs, compare Floyd–Warshall against repeated Bellman–Ford or repeated Dijkstra where its assumptions apply. Generate random graphs, include disconnected components, zero edges, negative edges without negative cycles, and deliberately constructed negative cycles. Agreement between independent methods is powerful evidence.
25. Common Learning Failure States
- Applying Dijkstra directly when negative edges are present.
- Confusing a negative edge with a negative cycle.
- Memorising Floyd–Warshall loops without the intermediate-vertex state.
- Reordering loops and silently breaking the invariant.
- Forgetting infinity guards before addition.
- Computing distances correctly but reconstructing paths incorrectly.
- Using Johnson reweighting without proving transformed weights are non-negative.
- Choosing by Big-O alone without considering density and memory layout.
26. A Beginner-to-Professional Learning Ladder
- Level 1: solve all-pairs distances on a four-vertex graph by repeated manual search.
- Level 2: initialize a distance matrix correctly.
- Level 3: trace one Floyd–Warshall intermediate stage.
- Level 4: explain and prove the recurrence.
- Level 5: reconstruct paths and detect a negative cycle.
- Level 6: derive Johnson’s reweighting equation.
- Level 7: explain why reweighting preserves shortest paths.
- Level 8: choose Floyd–Warshall, repeated Dijkstra or Johnson from graph properties.
- Level 9: benchmark matrix and sparse implementations on realistic graph families.
- Level 10: engineer blocked, parallel and numerically safe implementations with independent verification.
27. Teach the Matrix as a Sequence of Claims
Do not present three nested loops first. Present one matrix and ask: “What routes are legal before vertex k is allowed? What new routes become legal after?” Have learners predict one cell, run the update, investigate disagreement, modify the graph, then reconstruct the rule. This keeps the algorithm attached to meaning.
28. Use Subgoal-Labeled Worked Examples
Label the reasoning phases define state → establish base matrix → admit one intermediate → compare old route versus route through k → preserve path evidence. Subgoal-labelled worked examples have shown benefits for early programming problem solving and can reduce avoidable cognitive load for novices: Margulieux, Morrison and Decker.
29. Fade the Worked Example Toward Selection
First provide a completed matrix update. Next remove selected cells. Then ask the learner to derive the recurrence. Finally give only graph properties and ask which all-pairs family should be used. Professional learning requires moving from procedure execution to algorithm selection.
AI Assistance Boundary
AI can generate small graphs, check a matrix, propose counterexamples or explain a failed implementation. The learner should still state the invariant, predict updates before viewing answers, verify negative-cycle claims independently, and justify algorithm choice from the graph’s actual properties.
How Do We Know?
- MIT 6.006 — APSP and Johnson
- MIT 6.006 — Floyd–Warshall Dynamic Programming
- Princeton Algorithms — FloydWarshall
- Subgoal-Labeled Worked Examples in Introductory Programming
Evidence Boundary
Textbook complexity does not settle performance on every graph or machine. Memory hierarchy, priority-queue implementation, numeric representation, path-output requirements and graph density can reverse practical rankings. Use theory to preserve correctness and narrow choices; use representative measurements to choose production details.
Professional Direction
Advanced study includes blocked and cache-oblivious Floyd–Warshall, GPU APSP, min-plus matrix multiplication, distance oracles, dynamic APSP, graph sparsification, parallel shortest paths, path witnesses, negative-cycle propagation and specialized road-network preprocessing.
Algorithm-learning rule: when every pair matters, first decide whether the graph is sparse or dense and whether negative edges exist. Then choose the state space that makes the proof simple, preserve path evidence, and treat memory movement as part of the professional algorithm.
