Memra

All-pairs shortest paths: Floyd-Warshall

◈ 4 cards

A dynamic program over which vertices are allowed as intermediates — Θ(V³), handles negative edges, detects negative cycles on the diagonal.

All-pairs shortest paths

Sometimes you need for every pair of vertices, not just from one source — an distance matrix . You could run a single-source algorithm times, but Floyd-Warshall solves it directly in for arbitrary (including negative) edge weights, with a clean DP.

The DP over intermediate vertices

The insight is to parameterize by which vertices are allowed in the middle of a path. Define as the weight of a shortest path from to whose intermediate vertices all come from . Now consider a shortest such path: either vertex is not an intermediate (so the path is already optimal using ), or it is — and then it splits into and , each using only as intermediates. That gives the two-case recurrence: The base is the direct edge weight ( on the diagonal, if no edge). The final matrix holds the true shortest distances .

Running time, space, and negative cycles

Three nested loops — outermost, then , then — give , with only space if you overwrite the matrix in place. The algorithm handles negative edges, and a negative-weight cycle reveals itself as a negative diagonal entry (a path from a vertex back to itself that costs less than ). For sparse graphs, Johnson's algorithm reweights via Bellman-Ford and runs Dijkstras for — faster than when is small.

Worked example

On the CLRS Fig 23.1 graph (5 vertices, several negative edges, no negative cycle) Floyd-Warshall produces the full distance matrix shown in the exercise below. Notice the matrix is not symmetric — the graph is directed.

12345i=1038−4i=2017i=340i=42−50i=560k = 0: direct edges only.
D⁽⁰⁾ = W, the base case: no vertex is allowed as an intermediate yet, so every entry is a direct edge weight, 0 on the diagonal, or ∞. Row i, column j reads "best i→j path so far". The matrix is not symmetric, because the graph is directed.
12345i=1038−4i=2017i=340i=425−50−2i=560k = 1: only row 4 improves.
D⁽¹⁾: vertex 1 may now sit in the middle of a path, so every entry is tested against d[i][1] + d[1][j]. Only row 4 has a finite d[4][1] (= 2) to route through, so only row 4 changes: 4→1→2 costs 2 + 3 = 5, and 4→1→5 costs 2 + (−4) = −2. Repeat for k = 2, 3, 4, 5 and D holds every δ(i,j).
NORMAL ~/memra/learn/comp-372/floyd-warshall utf-8 LF