Floyd-Warshall Algorithm
Concept
Floyd-Warshall computes the shortest path between every pair of nodes in a weighted graph. It uses dynamic programming: for each intermediate node k, it checks if going through k gives a shorter path between every pair (i, j).
When to Use
- ▸All-pairs shortest path (distance from every node to every other node)
- ▸Small graphs (V <= 500) where you need all distances
- ▸Transitive closure (checking reachability between all pairs)
- ▸Problems that query shortest path between many different pairs
Intuition
Start with direct edge weights. Then ask: 'Can we do better by routing through node 0?' Update all pairs. Then ask: 'Can we do better by also routing through node 1?' And so on for every node. After considering all possible intermediate nodes, we have the shortest path for every pair. The triple nested loop is deceptively simple but powerful.
Complexity
Time
O(V^3)
Space
O(V^2)
Template Code
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
ios_base::sync_with_stdio(0), cin.tie(0);
int n, m;
cin >> n >> m;
const int inf = 1e9+7;
vector<vector<int>> adj(n, vector<int>(n, inf));
for(int i = 0; i < n; i++) adj[i][i] = 0;
int u, v, w;
for(int i = 0; i < m; i++){
cin >> u >> v >> w;
adj[u][v] = w;
}
for(int k = 0; k < n; k++){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if(adj[i][k] + adj[k][j] < adj[i][j]){
adj[i][j] = adj[i][k] + adj[k][j];
}
}
}
}
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if(adj[i][j] == inf) cout << "inf ";
else cout << adj[i][j] << " ";
}
cout << "\n";
}
return 0;
}
// Sample Input:
// 4 5
// 0 1 3
// 0 3 7
// 1 2 2
// 2 3 1
// 3 1 2
//
// Sample Output:
// 0 3 5 6
// inf 0 2 3
// inf 3 0 1
// inf 2 4 0