← SciSim / Computer Science

■ Floyd-Warshall

All-Pairs Shortest Path | DP on Vertices | O(V^3)

Standard Undergraduate

§1 — Interactive Simulation

Ready. Press Play or Next to begin.
Speed:
0
Operations
0
Comparisons
0/0
Step
n / size
FLOYD-WARSHALL(W): // W = V x V weight matrix
  dist = copy of W // dist[i][i]=0, no edge=INF
  for k = 1 to V: // use vertex k as intermediate
    for i = 1 to V:
      for j = 1 to V:
        if dist[i][k]+dist[k][j] < dist[i][j]:
          dist[i][j] = dist[i][k]+dist[k][j]
          next[i][j] = next[i][k]
  // Negative cycle: check dist[i][i] < 0

§2 — The Idea, Step by Step

Picture a printed table of driving times between every pair of towns. You know the times on the direct roads, but some towns have no direct road, and sometimes a direct road is slow. Floyd-Warshall fills in the whole table by asking one simple question, over and over: "Could I get from town $i$ to town $j$ faster if I passed through some other town along the way?"
Name the pieces. Lay the towns out in a grid. Let $dist[i][j]$ be the best travel time found so far from $i$ to $j$. Start with the direct-road times: $dist[i][i]=0$, and "no road yet" counts as $\infty$. Now pick one town $k$ and let it be a possible stopover. For every pair $(i,j)$, compare the route you already have against the detour that goes through $k$: $$dist[i][j] \;\leftarrow\; \min\big(dist[i][j],\; dist[i][k] + dist[k][j]\big).$$ Worked number: suppose the direct road A→B takes 9, but A→C takes 4 and C→B takes 3. Going through C costs $4+3 = 7$, which beats 9, so $dist[A][B]$ drops from 9 to 7.
The trick is the order. Wrap that one-line update in three nested loops, with the stopover $k$ on the OUTSIDE: "for each $k$, then for every $i$, then every $j$." This gives a dynamic-programming guarantee: after the $k$-th pass, $dist[i][j]$ holds the shortest trip that is allowed to use only towns $\{1,\dots,k\}$ as intermediate stops. Once $k$ has swept through all $V$ towns, every vertex is a legal stopover and the table holds the true shortest paths. Three loops of size $V$ cost $O(V^3)$ time, while reusing one grid keeps space at $O(V^2)$. The method even tolerates negative edge weights; the one thing it cannot handle is a negative cycle, which reveals itself afterwards as some $dist[i][i] < 0$.
Try this in the panel above. Step forward with ▶│ and watch the Operations and Comparisons counters climb — each step stands for one comparison the algorithm makes as it grinds through the table pair by pair. Next, drag the $n$ slider from 4 up toward 16 and watch the step count climb steeply — a hint of how all-pairs work explodes with size (the true Floyd-Warshall cost is $O(V^3)$, so tripling the vertices multiplies the work about $27$-fold, since $3^3 = 27$). Finally, set the speed to 0.25× and replay to follow each comparison one at a time.

§3 — Algorithm Analysis & Derivation

SymbolMeaning
nInput size (vertices V, edges E, or array length)
T(n)Time complexity function
W(n)Worst-case complexity
A(n)Average-case complexity
hHeight or depth of structure
kNumber of distinct values / items
Step 1 -- DP Formulation. Let dist_k[i][j] = shortest path from i to j using only vertices {1,...,k} as intermediates. Base case: dist_0[i][j] = w(i,j) (direct edge or INF). Recurrence: dist_k[i][j] = min(dist_{k-1}[i][j], dist_{k-1}[i][k] + dist_{k-1}[k][j]).
Step 2 -- Optimal Substructure. The shortest path from i to j using {1,...,k} either: (a) doesn't use vertex k -- same as dist_{k-1}[i][j], or (b) goes through k -- dist_{k-1}[i][k] + dist_{k-1}[k][j]. Taking minimum gives the recurrence.
Step 3 -- Space Optimization. The k-th update of dist[i][j] only reads dist[i][k] and dist[k][j]. Since dist[i][k] and dist[k][j] are not updated when the outer loop has index k (dist[x][k] is unchanged), we can use a single 2D array instead of a 3D array.
Step 4 -- Time O(V^3) Space O(V^2). Three nested loops, each iterating V times: O(V^3). Single 2D distance matrix: O(V^2). For V=1000: 10^9 operations -- may be slow. For V=500: feasible.
Step 5 -- Negative Cycle Detection. After algorithm runs: if dist[i][i] < 0 for any vertex i, there is a negative cycle containing i. Initially dist[i][i]=0; only becomes negative if i is on a negative cycle.
Step 6 -- vs Running Dijkstra/Bellman-Ford V times. V x Dijkstra: O(V(V+E) log V). V x Bellman-Ford: O(V^2 E). Floyd-Warshall: O(V^3). For dense graphs (E=V^2): V x Dijkstra = O(V^3 log V) > Floyd-Warshall. For sparse graphs: V x Dijkstra wins.

§4 — Frequently Asked Questions

What problem does Floyd-Warshall solve? concept+
All-Pairs Shortest Path (APSP): find shortest path between EVERY pair of vertices (i,j). Output: V x V matrix where dist[i][j] = shortest path distance from i to j. Also handles negative edges (but not negative cycles).
What does the outer loop variable k mean? concept+
After the k-th iteration of the outer loop, dist[i][j] = length of shortest path from i to j that only uses vertices from {1,2,...,k} as intermediate vertices. After all V iterations, all vertices are available as intermediates -- giving true shortest paths.
How to reconstruct the actual shortest path? applied+
Maintain a next[i][j] matrix: next[i][j] = next vertex on shortest path from i to j. Initialize next[i][j] = j for direct edges. Update: when dist[i][j] improves via k, set next[i][j] = next[i][k]. To trace path i->j: follow next[i][j] until reaching j.
When to use Floyd-Warshall vs V x Dijkstra? complex+
Dense graphs (E ~ V^2): Floyd-Warshall O(V^3) vs V x Dijkstra O(V^3 log V) -- Floyd wins. Sparse graphs (E ~ V): V x Dijkstra O(V^2 log V) vs Floyd O(V^3) -- Dijkstra wins. Negative edges: Floyd wins (Dijkstra fails). Simple implementation: Floyd is 5 lines.
What is transitive closure and its relation to Floyd-Warshall? nonobv+
Transitive closure: can vertex i reach vertex j? Replace min with OR, + with AND in Floyd-Warshall. If dist[i][k] AND dist[k][j] then dist[i][j] = true. This gives the reachability matrix in O(V^3). Warshall's original algorithm (1962) computed transitive closure; Floyd extended it to shortest paths.
How is Floyd-Warshall related to matrix multiplication? deep+
The (min,+) semiring: Floyd-Warshall computes the 'matrix power' of the adjacency matrix under (min,+) instead of standard (+,x). Shortest paths = tropical matrix multiplication. This connection enables O(V^3 / log V) APSP algorithms and connects to algebraic path problems.

§5 — Common Misconceptions & Errors

Conceptual Misconceptions

✗ Floyd-Warshall works only for non-negative weights.

✓ Floyd-Warshall handles negative edges. It fails ONLY for negative CYCLES (undefined shortest paths). Check dist[i][i] < 0 to detect negative cycles.

✗ The order of the three loops can be interchanged.

✓ The OUTER loop must be k (intermediates). The inner i,j loops can be interchanged. Swapping k with i or j gives wrong answers because dist[i][k] must be the k-1 value when updating dist[i][j] via k.

✗ Floyd-Warshall requires O(V^3) space.

✓ Space is O(V^2) for the distance matrix. The V iterations of k reuse the same matrix. No 3D array needed.

Implementation Errors

✗ Initializing non-existent edges to 0 instead of INF.

✓ Non-existent edges must be INF (infinity). Setting to 0 incorrectly implies a zero-cost path between unconnected vertices.

✗ Checking dist[i][i] for negative cycles DURING the algorithm.

✓ Check for negative cycles AFTER all V iterations complete. Checking during may miss cycles that form through later intermediate vertices.

✗ Using INT_MAX for infinity and adding to it (overflow).

✓ dist[i][k] + dist[k][j] overflows if either is INT_MAX. Use a large sentinel like 1e9 or 1e18 that does not overflow when added.