Floyd-Warshall
All-pairs shortest paths by dynamic programming: D[i][j] after iteration k is the shortest path using only the vertices 0 to k as intermediates; the three nested loops and why k must be the outer one, O(V^3) time and O(V^2) space, negative edges and negative cycles (a negative diagonal), path reconstruction with a predecessor matrix, transitive closure (Warshall), and the comparison with running Dijkstra or Bellman-Ford from every vertex.
Why it exists
Sometimes the distances between all pairs of vertices are needed: a table of distances between cities, the routing tables of a small network, the answer to "can reach ?" for every pair. One could run Dijkstra or Bellman-Ford from every vertex; Floyd-Warshall instead does it with three nested loops and a matrix, in time. It is simple, handles negative edges, detects negative cycles, and is the standard example of a dynamic program over the set of allowed intermediate vertices.
Prerequisites
You need the dynamic programming recipe of state, recurrence and filling order (dynamic programming).
Precise definitions
All-pairs shortest paths. For a weighted directed graph on vertices , the matrix of shortest-path distances from to for every ordered pair.
Weight matrix : , the weight of the edge , and if there is no such edge.
Intermediate vertex. A vertex of a path other than its two ends.
State. is the weight of a shortest path from to all of whose intermediate vertices are in (: no intermediate vertex allowed, direct edges only).
How it works
The recurrence
A shortest path from to with intermediate vertices in either does not use vertex (then it is a shortest path with intermediates in ) or uses it once (a shortest path is simple): it consists of a shortest path from to and a shortest path from to , both with intermediates in :
The answer is . The code needs only one matrix, updated in place:
for (k = 0; k < V; k++)
for (i = 0; i < V; i++)
for (j = 0; j < V; j++)
if (d[i][k] + d[k][j] < d[i][j])
d[i][j] = d[i][k] + d[k][j];In-place update is safe: during iteration the row and the column do not change (without negative cycles, , so ), so the values read are those of . Time (exactly executions of the innermost test), space . The loop over must be the outermost: a loop order with inside gives wrong answers.
The page graph, step by step
The graph has vertices and the edges , , , , , , , . The program prints the matrix before the loop and after each value of ; is written inf.
#include <stdio.h>
#define N 5
#define INF 1000000
static void show(int d[N][N]) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (d[i][j] >= INF) printf(" inf");
else printf(" %3d", d[i][j]);
}
printf("\n");
}
}
int main(void) {
int d[N][N];
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++) d[i][j] = i == j ? 0 : INF;
d[0][1] = 3; d[0][2] = 5; d[1][2] = -2; d[1][3] = 4; d[2][3] = 2; d[3][0] = 6; d[3][4] = 1; d[4][1] = 2;
printf("D0 (only direct edges):\n");
show(d);
for (int k = 0; k < N; k++) { /* allow vertex k as an intermediate vertex */
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (d[i][k] < INF && d[k][j] < INF && d[i][k] + d[k][j] < d[i][j]) {
d[i][j] = d[i][k] + d[k][j];
}
}
}
printf("after k = %d:\n", k);
show(d);
}
int negative = 0;
for (int i = 0; i < N; i++) if (d[i][i] < 0) negative = 1;
printf("negative cycle: %s\n", negative ? "yes" : "no");
return 0;
}D0 (only direct edges):
0 3 5 inf inf
inf 0 -2 4 inf
inf inf 0 2 inf
6 inf inf 0 1
inf 2 inf inf 0
after k = 0:
0 3 5 inf inf
inf 0 -2 4 inf
inf inf 0 2 inf
6 9 11 0 1
inf 2 inf inf 0
after k = 1:
0 3 1 7 inf
inf 0 -2 4 inf
inf inf 0 2 inf
6 9 7 0 1
inf 2 0 6 0
after k = 2:
0 3 1 3 inf
inf 0 -2 0 inf
inf inf 0 2 inf
6 9 7 0 1
inf 2 0 2 0
after k = 3:
0 3 1 3 4
6 0 -2 0 1
8 11 0 2 3
6 9 7 0 1
8 2 0 2 0
after k = 4:
0 3 1 3 4
6 0 -2 0 1
8 5 0 2 3
6 3 1 0 1
8 2 0 2 0
negative cycle: noThe animation below shows the same run one improvement at a time: first the matrix of direct edges, then for each a step that says which vertex is now allowed and one step for every entry that improves, with the path that gives the improvement.
Floyd-Warshall on a 5-vertex graph, one improvement per step: start
Computed by a script, not typed- 1D[i][j] = weight of the edge i -> j (0 if i = j, infinity if none)
- 2D[i][j] = min(D[i][j], D[i][k] + D[k][j]) for k = 0, 1, ...
| from \ to | 0 | 1 | 2 | 3 | 4 |
|---|---|---|---|---|---|
| 0 | 0 | 3 | 5 | ∞ | ∞ |
| 1 | ∞ | 0 | -2 | 4 | ∞ |
| 2 | ∞ | ∞ | 0 | 2 | ∞ |
| 3 | 6 | ∞ | ∞ | 0 | 1 |
| 4 | ∞ | 2 | ∞ | ∞ | 0 |
D0
Step 0
D0: the distances using only direct edges (infinity if there is no edge). Rows are the start vertex i, columns the end vertex j. Vertex k = 0, 1, ... will be allowed one at a time as an intermediate vertex.
For example, with the entry improves from to : the path costs , cheaper than the direct edge. With many entries become finite for the first time: vertex links the vertices that could reach it with those it can reach. The final matrix has no negative diagonal entry, so the graph has no negative cycle.
Negative edges and negative cycles
Floyd-Warshall works with negative edges as long as there is no negative cycle. If there is one, some diagonal entry becomes negative (a path from back to of negative weight): check the diagonal after the loops. (Example: edges , , give .) In that case the other entries may be meaningless.
Recovering the paths
Keep a second matrix (the first vertex after on a shortest path to ), initialised to for every edge ; whenever improves through set . A path is then read by following from until . (Equivalently a predecessor matrix.)
Transitive closure (Warshall's algorithm)
To decide only whether is reachable from , use a Boolean matrix with and for each edge, and the same three loops with the update . After iteration , exactly if there is a path from to with intermediate vertices in . The result is the transitive closure of the edge relation, in time (checked against searches from every vertex). Searching from every vertex does the same job in , which is faster for sparse graphs.
Which algorithm for all pairs?
| Method | Time | Negative edges |
|---|---|---|
| Floyd-Warshall | yes (no negative cycle) | |
| Dijkstra from every vertex (binary heap) | no | |
| Bellman-Ford from every vertex | yes | |
| Johnson's algorithm (Bellman-Ford once to re-weight, then Dijkstra from every vertex) | yes |
For dense graphs () Floyd-Warshall's is as good as any and much simpler; for sparse graphs runs of Dijkstra (or Johnson's algorithm if there are negative edges) are faster.
Worked examples
EX 1A three-vertex run by hand
EasyEdges , , . : , , , others (diagonal ). : nothing enters vertex ( for ), no change. : is compared with : improves to . : no vertex leaves vertex : no change. Result: , , .
EX 2How many operations?
EasyThe innermost comparison runs times: for the page graph, for (about a second or a few). Space: numbers. The number of improvements is far smaller (the animation shows them one by one).
EX 3What does D after iteration k mean?
MediumIn the page run after the entry : the path costs , using only vertex as an intermediate, which is allowed. The entry is still after : the only way from to goes through vertex (), which is not yet allowed; after it becomes .
EX 4Transitive closure
MediumEdges , , . Warshall: : gives . : gives and gives . , : no new pairs. Closure: reaches ; reaches ; reaches ; vertex reaches nobody.
EX 5Typical statements
GATE level(a) Time of Floyd-Warshall: ; space . (b) Does it work with negative edges? Yes, unless there is a negative cycle. (c) How is a negative cycle detected? A negative entry on the diagonal. (d) What would go wrong if the loop over were innermost? The recurrence needs all paths with intermediates in finished before is added; with innermost they are not, and some shortest paths are missed. (e) For vertices running Dijkstra from each vertex with an array costs , the same as Floyd-Warshall, but without negative edges. (f) Warshall's algorithm computes: the transitive closure.
Cheat box
Cheat box
- : shortest path with intermediates in . Start: direct edges, diagonal , else .
- Loops: outermost, then , then . In place. time, space.
- Negative edges fine; a negative diagonal entry means a negative cycle.
- Paths: keep a next/predecessor matrix.
- Warshall: same loops with OR/AND transitive closure.
- All-pairs alternatives: Dijkstra times (no negative edges), Johnson (negative edges, sparse).
Traps and GATE patterns
Connections
Builds on
Across subjects
No cross-subject links yet.
Floyd-Warshall is a dynamic program over the allowed intermediate vertices. It computes for all pairs what Dijkstra and Bellman-Ford compute for one source, and its Boolean form computes the reachability that depth-first search and strongly connected components find by searching.
PYQs
2 previous year questions from your book. I re-solved each one myself (1 by running or simulating, 1 by reasoning only); the book's key is shown next to my answer. All PYQs
The Asymptotic Notation of computing the transitive closure of a binary relation on a set of n elements is known to be:
- (a)O(n)
- (b)O(nlogn)
- (c)O(n3/2)
- (d)O(n3)
Consider the weighted undirected graph with 4
vertices, where the weight of edge {i, j} is given by
the entry W ij in the matrix W.Self-check
Question 1
What is the time and space of Floyd-Warshall for a graph with vertices?
Show answerHide
time and space.
Question 2
What does the entry represent?
Show answerHide
The weight of a shortest path from to whose intermediate vertices all belong to .
Question 3
How can you tell from the final matrix that the graph has a negative cycle?
Show answerHide
Some diagonal entry is negative.
Question 4
How many times does the innermost statement of the three loops execute for ?
Show answerHide
.
Revision card
One-screen revision
- ; outermost; in place.
- time, space; negative edges OK; negative diagonal negative cycle.
- Warshall: OR/AND, transitive closure. Paths via a next matrix.
- Sparse graphs: times Dijkstra, or Johnson.
References
- ·Cormen, Leiserson, Rivest, Stein, Introduction to Algorithms (3rd edition), Chapter 25 All-Pairs Shortest Paths (25.2 the Floyd-Warshall algorithm, 25.2 transitive closure)
- ·Sedgewick and Wayne, Algorithms (4th edition), Section 4.4 and Section 4.2 (Warshall's algorithm for transitive closure)
- ·Dasgupta, Papadimitriou, Vazirani, Algorithms, Section 6.6 All-pairs shortest paths
Verification
On 300 random directed graphs of up to 6 vertices every row of the Floyd-Warshall matrix was compared with a brute force over ALL simple paths, and for every k the matrix after iteration k was compared with the shortest path whose intermediate vertices all lie in {0, ..., k}. Negative cycles produced a negative diagonal entry; the transitive closure by the same three loops with OR and AND equalled reachability found by search. The matrix of the page graph was also compared with Bellman-Ford from each of its five vertices. The table is a real run of the page code (one step per improved entry, the single assignment instrumented) and its final matrix equals the printed one. Textbook chapter references are from memory. Johnson's algorithm is mentioned from the literature and not tested. SECOND PASS (2026-11-02, done by the assistant, not a human check): every Self-check question was solved before the printed answer was read and all agreed; the definitions, worked examples, cheat box and traps were read claim by claim and the numbers re-derived by hand or by a small script (loop counts, recurrences, merge and quicksort counts and averages, hash probes and load-factor formulas, DP tables, MST and shortest-path runs, Floyd matrices); long C programs were not re-read line by line (they are compiled and compared by npm run verify:c, and their printed outputs were checked against the prose); tables and animations are machine output and were read, not re-run; No other defect found. Status raised to self-checked; verified needs a textbook or human check.
last verified: never
My notes (saved in this browser)