Floyd's Algorithm: All-Pairs Shortest Paths
Shortest distances between every pair of vertices in one Θ(V³) sweep — swap Warshall's OR/AND for min/+ and the same three loops compute distances instead of reachability. Handles negative edges, and the diagonal exposes negative cycles.
From 'can I get there?' to 'how cheaply?'
Warshall's algorithm answers reachability for every pair. Floyd's algorithm (often Floyd–Warshall) upgrades the same three-loop skeleton to compute shortest distances for every pair:
D[i][j]= the minimum total weight of any path fromitoj.
The transformation is one substitution. Where Warshall combines facts with OR / AND:
Floyd combines costs with min / +:
Read it aloud: "the best way from i to j is either what I already know, or going via k — whichever is cheaper."
When do you want all pairs at once? Route-planning tables, computing a graph's diameter, finding the cheapest cycle, or as a preprocessing step when many distance queries follow. And because it never settles anything (unlike Dijkstra), negative edges are fine — only negative cycles are off-limits, and Floyd even detects those.
The recurrence — allow one more stopover at a time
Exactly like Warshall, define D⁽ᵏ⁾[i][j] = the length of the shortest i → j path whose intermediate vertices all come from {1, …, k}:
D⁽⁰⁾= the weight matrix:w(i→j)where an edge exists,0on the diagonal,∞elsewhere.- Going from
k−1tok: the best path allowed to usekeither skipsk(costD⁽ᵏ⁻¹⁾[i][j]) or passes through it exactly once (costD⁽ᵏ⁻¹⁾[i][k] + D⁽ᵏ⁻¹⁾[k][j]). Take the minimum. D⁽ⁿ⁾= true shortest distances.
This is dynamic programming on the set of allowed intermediates — the subproblem index is k, not a vertex or a path.
Negative cycle detection: the diagonal starts at D[i][i] = 0. If any D[i][i] ever drops below zero, vertex i lies on a cycle whose total weight is negative — at that point "shortest path" stops being well-defined for pairs that can detour through that cycle.
Step-by-step visualization
Run Floyd on a 4-vertex weighted digraph (edges 1→3 (3), 2→1 (2), 3→2 (7), 3→4 (1), 4→1 (6)). Step forward and backward with the ← / → arrow keys or the buttons below.
What to watch:
- For each intermediate k (cyan row/column), every pair
(i, j)is asked: is the detouri → k → jcheaper? The two cyan cells are the detour halvesD[i][k]andD[k][j]; the amber-ringed cell is the targetD[i][j]. Improvements flash green. - Early
∞entries melt away as detours appear:D[2][3]becomes2 + 3 = 5the momentk = 1lets paths hop through vertex1. - At
k = 3the matrix fills in fastest — vertex3is the graph's main junction (1→3and3→everything). - The very last improvement (
k = 4) shortensD[3][1]from9to7via3 → 4 → 1— even an already-finite entry can keep improving until the final round.
The digraph — cyan = intermediate vertex k, amber = the pair (i, j) being checked.
Distance matrix D
Tip: step through with the ← / → arrow keys.
Pseudocode
Identical shape to Warshall — three loops, k outermost — with min/+ in the middle and an ∞-guard so that nonexistent paths don't poison the arithmetic. Path reconstruction needs one extra matrix next[i][j] (the first hop on the best known i → j path), updated whenever a detour wins. The C++ tab runs the visualization's graph and prints the final distance matrix.
1FLOYD(weight matrix W[1..n][1..n]):2 // W[i][j] = edge weight, 0 on the diagonal, ∞ if no edge3 D = W // D(0): direct edges only45 for k = 1 to n: // allow vertex k as a stopover6 for i = 1 to n:7 for j = 1 to n:8 if D[i][k] + D[k][j] < D[i][j]: // detour via k is cheaper9 D[i][j] = D[i][k] + D[k][j]10 next[i][j] = next[i][k] // (optional) path tracking1112 // Negative-cycle check:13 for i = 1 to n:14 if D[i][i] < 0: report "negative cycle through i"1516 return D1718// Reconstruct the path i -> j using next[][]19// (next[i][j] = first hop of the best i -> j path; init next[i][j] = j for edges):20PATH(i, j):21 if D[i][j] == ∞: return "unreachable"22 P = [i]23 while i != j:24 i = next[i][j]25 append i to P26 return P
Complexity analysis
The same accounting as Warshall:
- Time: Θ(V³) — three loops, constant work inside, no dependence on
E. - Space: Θ(V²) for the distance matrix (plus another
V²fornextif you need actual paths). The in-place update is safe: during roundk, the cellsD[i][k]andD[k][j]cannot themselves improve in that round (a detour throughkdoesn't shorten a path tok— that would require a negativeD[k][k], i.e. a negative cycle).
How it compares for all-pairs distances:
| Approach | Time | Negative edges |
|---|---|---|
| Floyd | Θ(V³) | ✓ (no negative cycles) |
| Dijkstra × V | O(V·(V + E) log V) | ✗ |
| Bellman–Ford × V | O(V²·E) | ✓ |
For dense graphs (E ≈ V²) Floyd matches Dijkstra-from-every-vertex while being dramatically simpler — about five lines of code with no data structures. For large sparse graphs with non-negative weights, repeated Dijkstra wins.
Complexity Analysis
Time Complexity
Θ(V³) — independent of the number of edges.
Space Complexity
Θ(V²) for the distance matrix, updated in place; another Θ(V²) if you also track next[][] for path reconstruction.
Negative edges are fine; negative cycles are not (detected by a negative diagonal entry). For large sparse graphs with non-negative weights, running Dijkstra from every vertex is asymptotically faster.