Graphs · Medium

389. Floyd-Warshall - All-Pairs Shortest Paths

Topics: Graph, Matrix

Solve it on DeVert Campus - free code runner

Problem

Given a directed weighted graph with n vertices (0-indexed) and m edges (each u, v, weight - weights may be negative, but there is no negative-weight cycle anywhere in the graph), find the shortest distance between every pair of vertices using the Floyd-Warshall algorithm. Print n lines, each with n space-separated distances (row i, column j = shortest distance from i to j); print 'INF' where no path exists, and 0 on the diagonal.

Input and output

Input: The first line contains n, the number of vertices. The second line contains m, the number of edges. Each of the next m lines contains three integers u v w, a directed weighted edge (weights may be negative, with no negative cycle). Output: Print n lines, each with n space-separated distances, where 'INF' marks unreachable pairs and the diagonal is 0.

Example

Input:
4
8
0 1 5
1 0 5
1 2 3
2 1 3
2 3 1
3 2 1
0 3 10
3 0 10
Output:
0 5 8 9
5 0 3 4
8 3 0 1
9 4 1 0

Constraints

1 <= n <= 500

Key observation

Floyd-Warshall is specifically the right tool when you need ALL PAIRS' distances - for a SINGLE source's shortest paths, Dijkstra (non-negative weights) or Bellman-Ford (handles negative weights) alone is more efficient than running the full O(n³) all-pairs algorithm.

Intuition

Find the shortest distance between every pair of vertices in a weighted graph, all at once. Brute force: Run Dijkstra's or Bellman-Ford's algorithm separately from EVERY single vertex as a source - this works (giving the same all-pairs result) but requires n separate runs, each with its own overhead, when Floyd-Warshall computes everything in one unified triple-loop. Optimised: The KEY insight is considering vertices as INTERMEDIATE stops one at a time (the outermost loop variable k) - after processing vertex k, the matrix correctly reflects the shortest paths that are allowed to use ONLY vertices 0 through k as intermediate stops, and by the time all n vertices have been considered as k, every possible intermediate combination has been accounted for.

Better - Johnson's Algorithm

First run a single Bellman-Ford pass from an added virtual source connected to all vertices with 0-weight edges, producing potentials h(v) used to reweight every edge to a non-negative value without changing which paths are shortest. With all edges now non-negative, run Dijkstra's algorithm (with a binary heap) from every vertex to get all-pairs shortest paths in O(n*m log n) total, then convert distances back using the potentials. This is faster than repeated Bellman-Ford on sparse graphs, but it is considerably more complex to implement correctly than a direct DP. Time: O(n*m log n + n*m) Space: O(n^2)

Optimal - Floyd-Warshall DP

Initialize dist[i][j] as the direct edge weight (or infinity if none, 0 on the diagonal), then for each vertex k from 0 to n-1, update every pair dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]) - meaning 'is it shorter to go from i to j via k'. After allowing every vertex in turn as an intermediate stop, dist[i][j] holds the true shortest distance for every pair. This handles negative edge weights directly (as long as there's no negative cycle) with a simple triple-nested loop and no auxiliary graph transformations, making it the simplest and most reliable choice for the given constraint n <= 500. Time: O(n^3) Space: O(n^2)

Approach 3

Run the Bellman-Ford algorithm independently starting from each of the n vertices. Bellman-Ford correctly handles negative edge weights (as long as there's no negative cycle) by relaxing all m edges up to n-1 times per source. Doing this once per source vertex gives the full all-pairs distance matrix, but repeating an O(n*m) algorithm n times costs O(n^2 * m) overall, which is noticeably slower than necessary when the graph is dense. Time: O(n^2 * m) Space: O(n^2)

Step by step

1. Initialize an n x n distance matrix: 0 on the diagonal, direct edge weights where given, infinity everywhere else. 2. For every possible INTERMEDIATE vertex k (as the OUTERMOST loop), and every pair (i, j), check if routing i to j THROUGH k (dist[i][k] + dist[k][j]) beats the current dist[i][j] - update if so. 3. After considering every vertex as a possible intermediate stop, the matrix holds the true shortest distance between every pair.

Complexity

Time: O(n³) - the triple nested loop over all (k, i, j) combinations. Space: O(n²), for the distance matrix.

Edge cases

Test n = 1 (a single line printing just 0), a graph with disconnected vertex pairs (printed as 'INF'), and n at the upper bound of 500 for the O(n^3) algorithm.

Interview tip

Be ready to explain WHY the loop order matters so critically (k must be the OUTERMOST loop) - processing i or j as the outer loop instead would break the algorithm's correctness, since it relies on k's paths being FULLY finalized before being used as an intermediate for other pairs.

All DSA problems