GeeksforGeeks Medium

Floyd–Warshall Algorithm

Floyd Warshall is a GFG problem (Medium). You are given a weighted directed graph with n vertices as an n × n matrix dist:

  • dist[i][j] is the weight of the edge from i to j;
  • dist[i][i] is 0;
  • 10^8 means there is no edge from i to j.

Update the matrix in place so that dist[i][j] becomes the shortest distance from every vertex i to every vertex j, keeping 10^8 where j cannot be reached from i. Edge weights may be negative, but the graph has no negative cycle.

With n at most 100, an O(n³) pass over every triple of vertices is about a million steps, which is fast enough.

Constraints
  • 1 <= V <= 100
  • -1000 <= weight <= 1000
  • V³ time makes this practical only for small dense graphs
  • A negative diagonal entry signals a negative cycle
graphshortest-pathdpall-pairs
Open on GeeksforGeeks ↗
02

Intuition

The Floyd Warshall algorithm (also called the Floyd algorithm) finds the shortest path between all pairs of vertices with one idea, applied n times.

After round k, dist[i][j] holds the shortest path from i to j that may stop only at vertices 0 … k. Each round asks one question for every pair: is going i → k → j shorter than the best i → j so far?

dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])

Once every vertex has been allowed as a stop, the matrix holds the true shortest distances. Each round builds on the one before it, which makes this dynamic programming.

The demo below steps through a Floyd Warshall algorithm example on four vertices, one relaxation at a time.

How to spot this pattern

The all pairs shortest path problem: shortest distances between every pair of vertices, on a small or dense graph (n up to a few hundred), possibly with negative edges. When the whole distance matrix is the answer, three loops beat running a single-source algorithm from every vertex.

03

Approach

Try it first

Before reading on: write the one-line update that tries vertex k as a stop between i and j. Then decide which of the three loops must be outermost, and why the other two orders give wrong answers.

1

Start from the edge matrix

dist already holds the direct edges, 0 on the diagonal and 10^8 for no edge. That is the answer when no intermediate vertex is allowed. Round 0 must see only direct edges; everything else is built from them.

2

Allow one more intermediate vertex per round

For k = 0 … n-1, try k as a stop on every path. After this round, paths may pass through any of 0 … k. Keep k as the outer loop: each round needs every distance from the previous round to be final.

3

Relax every pair through k

For every i and j: if both dist[i][k] and dist[k][j] are real (not 10^8) and their sum is smaller than dist[i][j], replace it. Going through k is either shorter or not; taking the minimum keeps the best of both. Skipping the 10^8 check can overflow and make an unreachable pair look reachable.

4

Read the matrix

After the last round, dist[i][j] is the shortest distance from i to j. A negative value on the diagonal, dist[i][i] < 0, means i lies on a negative cycle. After the last round every vertex has been allowed as a stop, so no shorter path can exist.

04

Floyd–Warshall Algorithm solution in Python | C++ | Java

▶1class Solution:
▶2 def floydWarshall(self, dist: List[List[int]]) -> None:
▶3 INF = 10**8
▶4 n = len(dist)
▶5 for k in range(n):
▶6 for i in range(n):
▶7 for j in range(n):
▶8 if dist[i][k] == INF or dist[k][j] == INF:
▶9 continue
▶10 if dist[i][k] + dist[k][j] < dist[i][j]:
▶11 dist[i][j] = dist[i][k] + dist[k][j]
graph37825120123dist0123003∞71802∞25∞0132∞∞0direct edges only, no stops yet
n4vertices
allowed stopsnonepaths are single edges
Round 0 has not started. The matrix is just the edge list: 0 on the diagonal, the weight where an edge exists, ∞ where it does not. Each round k will allow one more vertex as a stop in the middle of a path.
graph37825120123kdist0123003∞71802∞25∞0132∞∞0round 0: allow stop 0
k0new allowed stop
allowed stops{0}after this round
Round 0. For every pair, try the detour i → 0 → j. Its cost is dist[i][0] (row 0's column, green) plus dist[0][j] (row 0, green). Row and column 0 themselves cannot improve in this round, which is why updating in place is safe.
graph37825120123kdist0123003∞718021525∞0132∞∞01 → 08+0 → 37=new15<old∞15 < ∞ → write dist[1][3]
path1 → 0 → 3through the new stop
dist[1][3]15was ∞
Going 1 → 0 → 3 costs 8 + 7 = 15, and 1 could not reach 3 at all before. Write it into dist[1][3]; later rounds can build on it.
graph37825120123kdist0123003∞71802152580132∞∞02 → 05+0 → 13=new8<old∞8 < ∞ → write dist[2][1]
path2 → 0 → 1through the new stop
dist[2][1]8was ∞
Going 2 → 0 → 1 costs 5 + 3 = 8, and 2 could not reach 1 at all before. Write it into dist[2][1]; later rounds can build on it.
graph37825120123kdist0123003∞718021525801325∞03 → 02+0 → 13=new5<old∞5 < ∞ → write dist[3][1]
path3 → 0 → 1through the new stop
dist[3][1]5was ∞
Going 3 → 0 → 1 costs 2 + 3 = 5, and 3 could not reach 1 at all before. Write it into dist[3][1]; later rounds can build on it.
graph37825120123kdist0123003∞718021525801325∞0round 1: allow stop 1
k1new allowed stop
allowed stops{0..1}after this round
Round 1. For every pair, try the detour i → 1 → j. Its cost is dist[i][1] (row 1's column, green) plus dist[1][j] (row 1, green). Row and column 1 themselves cannot improve in this round, which is why updating in place is safe.
graph37825120123kdist01230035718021525801325∞00 → 13+1 → 22=new5<old∞5 < ∞ → write dist[0][2]
path0 → 1 → 2through the new stop
dist[0][2]5was ∞
Going 0 → 1 → 2 costs 3 + 2 = 5, and 0 could not reach 2 at all before. Write it into dist[0][2]; later rounds can build on it.
graph37825120123kdist01230035718021525801325703 → 15+1 → 22=new7<old∞7 < ∞ → write dist[3][2]
path3 → 1 → 2through the new stop
dist[3][2]7was ∞
Going 3 → 1 → 2 costs 5 + 2 = 7, and 3 could not reach 2 at all before. Write it into dist[3][2]; later rounds can build on it.
graph37825120123kdist0123003571802152580132570round 2: allow stop 2
k2new allowed stop
allowed stops{0..2}after this round
Round 2. For every pair, try the detour i → 2 → j. Its cost is dist[i][2] (row 2's column, green) plus dist[2][j] (row 2, green). Row and column 2 themselves cannot improve in this round, which is why updating in place is safe.
graph37825120123kdist01230035618021525801325700 → 25+2 → 31=new6<old76 < 7 → write dist[0][3]
path0 → 2 → 3through the new stop
dist[0][3]6was 7
Going 0 → 2 → 3 costs 5 + 1 = 6, cheaper than the 7 known so far. Write it into dist[0][3]; later rounds can build on it.
graph37825120123kdist01230035617021525801325701 → 22+2 → 05=new7<old87 < 8 → write dist[1][0]
path1 → 2 → 0through the new stop
dist[1][0]7was 8
Going 1 → 2 → 0 costs 2 + 5 = 7, cheaper than the 8 known so far. Write it into dist[1][0]; later rounds can build on it.
graph37825120123kdist0123003561702325801325701 → 22+2 → 31=new3<old153 < 15 → write dist[1][3]
path1 → 2 → 3through the new stop
dist[1][3]3was 15
Going 1 → 2 → 3 costs 2 + 1 = 3, cheaper than the 15 known so far. Write it into dist[1][3]; later rounds can build on it.
graph37825120123kdist012300356170232580132570round 3: allow stop 3
k3new allowed stop
allowed stops{0..3}after this round
Round 3. For every pair, try the detour i → 3 → j. Its cost is dist[i][3] (row 3's column, green) plus dist[3][j] (row 3, green). Row and column 3 themselves cannot improve in this round, which is why updating in place is safe.
graph37825120123kdist0123003561502325801325701 → 33+3 → 02=new5<old75 < 7 → write dist[1][0]
path1 → 3 → 0through the new stop
dist[1][0]5was 7
Going 1 → 3 → 0 costs 3 + 2 = 5, cheaper than the 7 known so far. Write it into dist[1][0]; later rounds can build on it.
graph37825120123kdist0123003561502323801325702 → 31+3 → 02=new3<old53 < 5 → write dist[2][0]
path2 → 3 → 0through the new stop
dist[2][0]3was 5
Going 2 → 3 → 0 costs 1 + 2 = 3, cheaper than the 5 known so far. Write it into dist[2][0]; later rounds can build on it.
graph37825120123kdist0123003561502323601325702 → 31+3 → 15=new6<old86 < 8 → write dist[2][1]
path2 → 3 → 1through the new stop
dist[2][1]6was 8
Going 2 → 3 → 1 costs 1 + 5 = 6, cheaper than the 8 known so far. Write it into dist[2][1]; later rounds can build on it.
graph37825120123dist012300356150232360132570all pairs shortest, done
rounds4one per vertex
resultdoneO(n³) relaxations
Done. After round 3 every vertex may appear as a stop, so each entry is the true shortest distance. Entries still ∞ are pairs with no path at all.
05

Common pitfalls

Putting k in an inner loop

✗ Wrong
for i in range(n):
    for j in range(n):
        for k in range(n):
            ...
✓ Right
for k in range(n):
    for i in range(n):
        for j in range(n):
            ...

With k innermost, dist[i][j] is finished before the entries it depends on have been improved, so paths that need two or more stops are missed. In the first example 1 → 0 needs the stops 2 and 3 (2 + 1 + 2 = 5), and the wrong order leaves it at 7.

Adding through a missing edge

✗ Wrong
if dist[i][k] + dist[k][j] < dist[i][j]:
✓ Right
if dist[i][k] == INF or dist[k][j] == INF:
    continue

In the second example dist[1][0] becomes 10^8 - 3, a fake distance to a vertex that 1 cannot reach. With INT_MAX as infinity in C++ or Java, INT_MAX + INT_MAX overflows to a negative number and wins every comparison.

06

Complexity

Time
O(n³)
Space
O(1)
Three nested loops over n vertices. The matrix is updated in place, so no extra space beyond the input. With n = 100 that is one million relaxations, which is instant; at n = 5,000 it is too slow and one Dijkstra per source on a sparse graph is better.
07

Floyd Warshall vs Dijkstra vs Bellman-Ford

All three find shortest paths. The number of sources and the sign of the weights decide which one fits.

AlgorithmSourcesNegative edges?Time
Floyd Warshallall pairsyes (detects negative cycles)O(V³)
Dijkstra (binary heap)onenoO((V + E) log V)
Bellman-Fordoneyes (detects negative cycles)O(V · E)
Dijkstra from every vertexall pairsnoO(V (V + E) log V)
08

Floyd–Warshall Algorithm FAQ

How does the Floyd Warshall algorithm work?
  • State: dist[i][j] = shortest distance from i to j using only intermediate vertices 0 … k.
  • Start: the edge matrix, with 0 on the diagonal and infinity for no edge.
  • Round k: for every pair, dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]).
  • End: after k = n - 1, every vertex is allowed, so dist holds all-pairs shortest distances.
  • Complexity: O(n³) time, O(1) extra space.
  • Negative cycles: some dist[i][i] < 0 after the loops.
What are the applications of the Floyd Warshall algorithm?

Distance tables between all cities in a small road network, routing tables, finding the vertex with the fewest reachable neighbours within a limit (LeetCode 1334), transitive closure of a relation (Warshall's algorithm, with or and and in place of min and +), and detecting negative cycles.

Can Floyd Warshall handle negative edge weights?

Yes. Unlike Dijkstra, it never assumes a distance is final early, so negative edges are fine. What it cannot handle is a negative cycle, because then no shortest path exists; it reports one as a negative diagonal entry.

What is the time complexity of the Floyd Warshall algorithm?

O(n³) time for n vertices, from the three nested loops, regardless of how many edges there are. Space is O(n²) for the matrix, or O(1) extra when it is updated in place.