Skip to content
Part IA Lent Term

Floyd-Warshall Algorithm

Overview

Floyd-Warshall solves the all-pairs shortest paths (APSP) problem using dynamic programming. It is particularly suited to dense graphs, running in Θ(∣V∣3)\Theta(|V|^3) time and Θ(∣V∣2)\Theta(|V|^2) space (in-place optimisation). It handles negative edge weights but, like all shortest-path algorithms, requires that no negative-weight cycles exist.

The DP Recurrence

Number the vertices 1,2,…,n1, 2, \ldots, n. Let dij(k)d_{ij}^{(k)} be the weight of a shortest path from ii to jj using only intermediate vertices from the set {1,2,…,k}\{1, 2, \ldots, k\}. The base case k=0k=0 uses no intermediate vertices:

dij(0)={0if i=jw(i,j)if (i,j)∈E∞otherwised_{ij}^{(0)} = \begin{cases} 0 & \text{if } i = j \\ w(i, j) & \text{if } (i, j) \in E \\ \infty & \text{otherwise} \end{cases}

For k≥1k \ge 1, vertex kk is either used as an intermediate vertex or not:

dij(k)=min⁡(dij(k−1),  dik(k−1)+dkj(k−1))d_{ij}^{(k)} = \min\left(d_{ij}^{(k-1)},\; d_{ik}^{(k-1)} + d_{kj}^{(k-1)}\right)

After k=nk = n, we have the full all-pairs shortest distances.

Pseudocode

FLOYD-WARSHALL(W):
  n = number of vertices
  D^(0) = W            // W is the weight matrix (∞ for absent edges)
  for k = 1 to n:
    let D^(k) be a new n × n matrix
    for i = 1 to n:
      for j = 1 to n:
        D^(k)[i][j] = min(D^(k-1)[i][j],
                          D^(k-1)[i][k] + D^(k-1)[k][j])
  return D^(n)

Space optimisation: The D(k−1)D^{(k-1)} matrix can be overwritten to produce D(k)D^{(k)} in place because dik(k−1)=dik(k)d_{ik}^{(k-1)} = d_{ik}^{(k)} and dkj(k−1)=dkj(k)d_{kj}^{(k-1)} = d_{kj}^{(k)} (paths where kk is an intermediate vertex cannot have kk as an endpoint). So a single n×nn \times n matrix suffices.

Worked Example

Consider a graph with V={1,2,3,4}V = \{1,2,3,4\}, edges and weights:

W=D(0)=(03∞7802∞5∞012∞∞0)W = D^{(0)} = \begin{pmatrix} 0 & 3 & \infty & 7 \\ 8 & 0 & 2 & \infty \\ 5 & \infty & 0 & 1 \\ 2 & \infty & \infty & 0 \end{pmatrix}

k=1k=1 (intermediate vertex {1}):

  • d2,3(1)=min⁡(d2,3(0),d2,1(0)+d1,3(0))=min⁡(2,8+∞)=2d_{2,3}^{(1)} = \min(d_{2,3}^{(0)}, d_{2,1}^{(0)} + d_{1,3}^{(0)}) = \min(2, 8+\infty) = 2
  • d2,4(1)=min⁡(∞,8+7)=15d_{2,4}^{(1)} = \min(\infty, 8+7) = 15
  • d3,2(1)=min⁡(∞,5+3)=8d_{3,2}^{(1)} = \min(\infty, 5+3) = 8
  • d4,2(1)=min⁡(∞,2+3)=5d_{4,2}^{(1)} = \min(\infty, 2+3) = 5

D(1)=(03∞780215580125∞0)D^{(1)} = \begin{pmatrix} 0 & 3 & \infty & 7 \\ 8 & 0 & 2 & 15 \\ 5 & 8 & 0 & 1 \\ 2 & 5 & \infty & 0 \end{pmatrix}

k=2k=2 (intermediate vertices {1,2}):

  • d1,3(2)=min⁡(∞,3+2)=5d_{1,3}^{(2)} = \min(\infty, 3+2) = 5
  • d3,4(2)=min⁡(1,8+15)=1d_{3,4}^{(2)} = \min(1, 8+15) = 1
  • d4,3(2)=min⁡(∞,5+2)=7d_{4,3}^{(2)} = \min(\infty, 5+2) = 7

D(2)=(03578021558012570)D^{(2)} = \begin{pmatrix} 0 & 3 & 5 & 7 \\ 8 & 0 & 2 & 15 \\ 5 & 8 & 0 & 1 \\ 2 & 5 & 7 & 0 \end{pmatrix}

k=3k=3 (intermediate vertices {1,2,3}):

  • d4,4(3)=min⁡(0,7+1)=min⁡(0,8)=0d_{4,4}^{(3)} = \min(0, 7+1) = \min(0,8) = 0 (no change).

D(3)=(same as D(2), no new paths)D^{(3)} = \text{(same as $D^{(2)}$, no new paths)}

k=4k=4:

  • d1,4(4)=min⁡(7,7+0)=7d_{1,4}^{(4)} = \min(7, 7+0) = 7 (unchanged)
  • All others checked; no improvements.

D(4)=D(2)D^{(4)} = D^{(2)}

The final matrix gives all-pairs distances. For example, δ(4,3)=7\delta(4,3) = 7 via path 4→1→2→34 \to 1 \to 2 \to 3 (cost 2+3+2=72+3+2=7).

Predecessor Matrix

To reconstruct paths, maintain a predecessor matrix Π(k)\Pi^{(k)} in parallel. Initialise πij(0)=i\pi_{ij}^{(0)} = i if (i,j)∈E(i,j) \in E or i=ji = j, else NIL. Update alongside the distance matrix: if the dik+dkjd_{ik} + d_{kj} path is chosen, set πij(k)=πkj(k−1)\pi_{ij}^{(k)} = \pi_{kj}^{(k-1)}.

Transitive Closure

Floyd-Warshall can compute the transitive closure G∗G^* of a graph: an edge (i,j)(i,j) exists in G∗G^* iff there is a path from ii to jj in GG. Replace MIN with logical OR and ++ with logical AND. Initialise dij(0)=1d_{ij}^{(0)} = 1 if i=ji = j or (i,j)∈E(i,j) \in E, 0 otherwise. Running the same triple loop yields the reachability matrix in Θ(∣V∣3)\Theta(|V|^3).

For DAGs, the transitive closure can be computed more efficiently by processing vertices in topological order.

Comparison with Johnson

AlgorithmTimeSpaceBest for
Floyd-WarshallΘ(V3)\Theta(V^3)Θ(V2)\Theta(V^2)Dense graphs
JohnsonO(V2log⁡V+VE)O(V^2 \log V + VE)Θ(V2)\Theta(V^2)Sparse graphs

When ∣E∣=Θ(∣V∣2)|E| = \Theta(|V|^2), both are Θ(∣V∣3)\Theta(|V|^3), but Floyd-Warshall has lower constant factors and is simpler to implement.

Summary

PropertyDetail
TypeDynamic programming
Recurrencedij(k)=min⁡(dij(k−1),dik(k−1)+dkj(k−1))d_{ij}^{(k)} = \min(d_{ij}^{(k-1)}, d_{ik}^{(k-1)} + d_{kj}^{(k-1)})
Base casedij(0)=w(i,j)d_{ij}^{(0)} = w(i,j) or 0 for i=ji=j
TimeΘ(V3)\Theta(V^3)
SpaceΘ(V2)\Theta(V^2) (in-place)
Negative weightsHandled (no negative cycles)
Transitive closureReplace min/+ with OR/AND

Past paper questions: y2026p1q10(c,d) (DAG transitive closure optimisation).