Below are some of the key points of Floyd-Warshall’s shortest path for all node pairs
Algorithm : Floyd-Warshall
1. Create a two-dimensional array of size n x n for storing the length of the shortest path between all node pairs. n is the number of nodes in the graph. Initialize all the cells of this array with ∞. 2. For every node i in the graph, initialize the distance of the node to itself as 0. Distance [ i ] [ i ] = 0. 3. For every edge ( u, v ) in the graph, initialize the distance array as the weight of the edge. Distance [ u ] [ v ] = Weight of (u, v) 4. For every node k in [ 1 … n ] do For every node i in [ 1 … n ] do For every node j in [ 1 … n ] do If ( Distance [ i ] [ j ] > Distance [ i ] [ k ] + Distance [ k ] [ j ] ) : Distance [ i ] [ j ] = Distance [ i ] [ k ] + Distance [ k ] [ j ]
Floyd-Warshall path construction example
Consider the shortest path in terms of weight / distance between node Source ( 1 ) - Destination ( 3 ) : [ 1 2 3 ] Case 1 : The shortest path from a node to itself is the node itself. i.e next [ i ] [ i ] = i. Example : next [ 1 ] [ 1 ] = 1 i.e Next node from 1 to reach 1 is 1. Example : next [ 3 ] [ 3 ] = 3 i.e Next node from 3 to reach 3 is 3. Case 2 : If the shortest path from node i to node j does not visit any intermediate node, next [ i ] [ j ] = j. Example : next [ 1 ] [ 2 ] = 2 i.e Next node from 1 to reach 2 is 2. Example : next [ 2 ] [ 3 ] = 3 i.e Next node from 2 to reach 3 is 3. Case 3 : If the shortest path from node i to node j visits an intermediate node k, next [ i ] [ j ] = next [ i ] [ k ] Example : next [ 1 ] [ 3 ] = next [ 1 ] [ 2 ] = 2 i.e Next node from 1 to 3 is 2.
To construct the path from Source 1 - Destination 3 the algorithm follows the below steps
Algorithm : Path construction ( Source src, Destination dst ) 1. If next [ src ] [ dst ] == -1 then no path exist. return empty path [ ]. 2. Insert path = [ src ] 3. While ( src != dst ) 4. source = next [ src ] [ dst ] 5. Append src to path
Graph type : Designed for directed weighted graphs containing positive and negative edge weights and no negative weight cycles.
Data structure used for storing graph : Edge list for storing the edges and their corresponding weights.
Time complexity : O ( N 3 ). N is the number of vertices / node in the graph.
Floyd-Warshall’s all pairs shortest path implementation.
# Example : Graph
# 1
# /|\
# / | \
# 9/ |7 \3
# / 3 | \
# 0----4----2
# \ | 1 /
# 2\ |1 /-2
# \ | /
# \|/
# 3
#
class Edge :
def __init__(self, src : int, dst : int, weight : int) :
self.src = src
self.dst = dst
self.weight = weight
class Graph:
def __init__(self, arg_nodes : int):
self.nodes = arg_nodes
# Edge weight is a dictionary for storing the weight of the edges { "src-dst" : weight }
self.edge_list = []
# distance is a 2-dimensional array that stores the shortest distance between [src][dst]
self.distance = [999999999] * arg_nodes
# next is a 2-dimensional array that stores the node next to the source. This is used
# for path construction between [src][dst]
self.next = [-1] * arg_nodes
for i in range(arg_nodes):
self.distance[i] = [999999999] * arg_nodes
self.next[i] = [-1] * arg_nodes
def AddEdge (self, src : int, dst : int, weight : int, isbidirectional = True):
e = Edge(src, dst, weight)
self.edge_list.append(e)
if (isbidirectional):
e = Edge(dst, src, weight)
self.edge_list.append(e)
def Floyd_Warshall (self):
for i in range (self.nodes):
self.distance[i][i] = 0
self.next[i][i] = i
for edge in self.edge_list:
weight = edge.weight
u = edge.src
v = edge.dst
self.distance[u][v] = weight
self.next[u][v] = v
for k in range(self.nodes):
for i in range(self.nodes):
for j in range(self.nodes):
if (self.distance[i][j] > self.distance[i][k] + self.distance[k][j]):
self.distance[i][j] = self.distance[i][k] + self.distance[k][j]
self.next[i][j] = self.next[i][k]
print("Shortest distance between nodes\n")
for u in range(self.nodes):
for v in range(u+1, self.nodes):
print("Distance ( " + str(u) + " - " + str(v) + " ) : " + str(self.distance[u][v]))
self.PathConstruction(u, v)
# Construct path from source node to destination node
def PathConstruction (self, src : int, dst : int):
print("# Path between " + str(src) + " and " + str(dst) + " : ", end = ' ')
if (self.next[src][dst] == -1):
print("No path exists")
else:
path = []
path.append(src)
while (src != dst):
src = self.next[src][dst]
path.append(src)
for node in path:
print(str(node) + " ", end = ' ')
print("\n")
def main():
g = Graph(5)
# Edges from node 0
g.AddEdge(0, 1, 9)
g.AddEdge(0, 3, 2)
g.AddEdge(0, 4, 3)
# Edges from node 1
g.AddEdge(1, 2, 3)
g.AddEdge(1, 4, 7)
# Edges from node 2
# Edge from 2 -> 3 is unidirectional. If it was bidirectional, it would introduce negative weight cycle
# causing the Floyd-Warshall algorithm to fail.
g.AddEdge(2, 3, -2, False)
g.AddEdge(2, 4, 1)
# Edges from node 3
g.AddEdge(3, 4, 1)
g.Floyd_Warshall()
if __name__ == "__main__":
main()
Output
Shortest distance between nodes
Distance ( 0 - 1 ) : 7
# Path between 0 and 1 : 0 4 2 1
Distance ( 0 - 2 ) : 4
# Path between 0 and 2 : 0 4 2
Distance ( 0 - 3 ) : 2
# Path between 0 and 3 : 0 3
Distance ( 0 - 4 ) : 3
# Path between 0 and 4 : 0 4
Distance ( 1 - 2 ) : 3
# Path between 1 and 2 : 1 2
Distance ( 1 - 3 ) : 1
# Path between 1 and 3 : 1 2 3
Distance ( 1 - 4 ) : 2
# Path between 1 and 4 : 1 2 3 4
Distance ( 2 - 3 ) : -2
# Path between 2 and 3 : 2 3
Distance ( 2 - 4 ) : -1
# Path between 2 and 4 : 2 3 4
Distance ( 3 - 4 ) : 1
# Path between 3 and 4 : 3 4
#include<iostream>
#include<list>
#include<vector>
using namespace std;
/*
1
/|\
/ | \
9/ |7 \3
/ 3 | \
0----4----2
\ | 1 /
2\ |1 /-2
\ | /
\|/
3
*/
class Edge {
public:
int src;
int dst;
int weight;
Edge () {}
Edge (int src, int dst, int weight) {
this->src = src;
this->dst = dst;
this->weight = weight;
}
};
class Graph {
private:
list<Edge> edge_list;
int nodes;
// distance is a 2-dimensional array that stores the shortest distance between [src][dst]
vector<vector<int>> distance;
// next is a 2-dimensional array that stores the node next to the source. This is used
// for path construction between [src][dst]
vector<vector<int>> next;
public:
Graph() {}
Graph (int n) {
nodes = n;
distance.resize(n);
next.resize(n);
for (int i=0; i<n; i++) {
distance[i].resize(n, 999999999); // 999999999 indicates infinite distance
next[i].resize(n, -1);
}
}
void AddEdge (int src, int dst, int weight, bool isbidirectional) {
Edge e(src, dst, weight);
edge_list.push_back(e);
if (isbidirectional) {
Edge e(dst, src, weight);
edge_list.push_back(e);
}
}
void Floyd_Warshall() {
for (int i=0; i<nodes; i++) {
distance[i][i] = 0;
next[i][i] = i;
}
for (auto edge : edge_list) {
int u = edge.src;
int v = edge.dst;
distance[u][v] = edge.weight;
next[u][v] = v;
}
for (int k=0; k<nodes; k++) {
for (int i=0; i<nodes; i++) {
for (int j=0; j<nodes; j++) {
if (distance[i][j] > distance[i][k] + distance[k][j]) {
distance[i][j] = distance[i][k] + distance[k][j];
next[i][j] = next[i][k];
}
}
}
}
cout << "Shortest distance between nodes" << endl;
for (int u=0; u<nodes; u++) {
for (int v=u+1; v<nodes; v++) {
cout << "\nDistance ( " << u << " - " << v << " ) : " << distance[u][v] << endl;
PathConstruction(u, v);
}
}
}
// Construct path from source node to destination node
void PathConstruction (int src, int dst) {
cout << "# Path between " << src << " and " << dst << " : ";
if (next[src][dst] == -1) {
cout << "No path exists" << endl;
} else {
vector<int> path;
path.push_back(src);
while (src != dst) {
src = next[src][dst];
path.push_back(src);
}
for (auto& it : path)
cout << it << " ";
cout << endl;
}
}
};
int main() {
Graph g(5);
// Edges from node 0
// AddEdge(src, dst, weight, bi-directional(true/false))
g.AddEdge(0, 1, 9, true);
g.AddEdge(0, 3, 2, true);
g.AddEdge(0, 4, 3, true);
// Edges from node 1
g.AddEdge(1, 2, 3, true);
g.AddEdge(1, 4, 7, true);
// Edges from node 2
// Edge from 2 -> 3 is unidirectional. If it was bidirectional, it would introduce negative weight cycle
// causing the Floyd-Warshall algorithm to fail.
g.AddEdge(2, 3, -2, false);
g.AddEdge(2, 4, 1, true);
// Edges from node 3
g.AddEdge(3, 4, 1, true);
g.Floyd_Warshall();
return 0;
}
Output
Shortest distance between nodes
Distance ( 0 - 1 ) : 7
# Path between 0 and 1 : 0 4 2 1
Distance ( 0 - 2 ) : 4
# Path between 0 and 2 : 0 4 2
Distance ( 0 - 3 ) : 2
# Path between 0 and 3 : 0 3
Distance ( 0 - 4 ) : 3
# Path between 0 and 4 : 0 4
Distance ( 1 - 2 ) : 3
# Path between 1 and 2 : 1 2
Distance ( 1 - 3 ) : 1
# Path between 1 and 3 : 1 2 3
Distance ( 1 - 4 ) : 2
# Path between 1 and 4 : 1 2 3 4
Distance ( 2 - 3 ) : -2
# Path between 2 and 3 : 2 3
Distance ( 2 - 4 ) : -1
# Path between 2 and 4 : 2 3 4
Distance ( 3 - 4 ) : 1
# Path between 3 and 4 : 3 4
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
/*
1
/|\
/ | \
9/ |7 \3
/ 3 | \
0----4----2
\ | 1 /
2\ |1 /-2
\ | /
\|/
3
*/
class Edge {
int src;
int dst;
int weight;
Edge(int src, int dst, int weight) {
this.src = src;
this.dst = dst;
this.weight = weight;
}
}
class Graph {
int nodes;
// distance is a 2-dimensional array that stores the
// shortest distance between [src][dst]
int distance[][];
// next is a 2-dimensional array that stores the node next to src.
// This is used for the path construction between [src][dst]
int next[][];
List<Edge> edge_list = new ArrayList<Edge>();
Graph (int n) {
nodes = n;
distance = new int[n][n];
next = new int[n][n];
for (int i=0; i<n; i++) {
Arrays.fill(distance[i], 999999999); // 999999999 indicates infinite distance
Arrays.fill(next[i], -1);
}
}
void AddEdge (int src, int dst, int weight, boolean isbidirectional) {
Edge e = new Edge(src, dst, weight);
edge_list.add(e);
if (isbidirectional) {
e = new Edge(dst, src, weight);
edge_list.add(e);
}
}
void Floyd_Warshall() {
for (int i=0; i<nodes; i++) {
distance[i][i] = 0;
next[i][i] = i;
}
for (Edge it : edge_list) {
int weight = it.weight;
int u = it.src;
int v = it.dst;
distance[u][v] = weight;
next[u][v] = v;
}
for (int k=0; k<nodes; k++) {
for (int i=0; i<nodes; i++) {
for (int j=0; j<nodes; j++) {
if (distance[i][j] > distance[i][k] + distance[k][j]) {
distance[i][j] = distance[i][k] + distance[k][j];
next[i][j] = next[i][k];
}
}
}
}
System.out.println( "Shortest distance between nodes");
for (int u=0; u<nodes; u++) {
for (int v=u+1; v<nodes; v++) {
System.out.println("\nDistance ( " + u + " - " + v + " ) : " + distance[u][v]);
PathConstruction(u, v);
}
}
}
// Construct path from source node to destination node
void PathConstruction (int src, int dst) {
System.out.print("# Path between " + src + " and " + dst + " : ");
if (next[src][dst] == -1) {
System.out.println( "No path exists");
} else {
List<Integer> path = new ArrayList<Integer>();
path.add(src);
while (src != dst) {
src = next[src][dst];
path.add(src);
}
for (int n : path)
System.out.print(n + " ");
System.out.println();
}
}
public static void main(String[] args) {
Graph g = new Graph(5);
// Edges from node 0
g.AddEdge(0, 1, 9, true);
g.AddEdge(0, 3, 2, true);
g.AddEdge(0, 4, 3, true);
// Edges from node 1
g.AddEdge(1, 2, 3, true);
g.AddEdge(1, 4, 7, true);
// Edges from node 2
// Edge from 2 -> 3 is unidirectional. If it was bidirectional, it would introduce negative weight cycle
// causing the Floyd-Warshall algorithm to fail.
g.AddEdge(2, 3, -2, false);
g.AddEdge(2, 4, 1, true);
// Edges from node 3
g.AddEdge(3, 4, 1, true);
g.Floyd_Warshall();
}
}
Output
Shortest distance between nodes
Distance ( 0 - 1 ) : 7
# Path between 0 and 1 : 0 4 2 1
Distance ( 0 - 2 ) : 4
# Path between 0 and 2 : 0 4 2
Distance ( 0 - 3 ) : 2
# Path between 0 and 3 : 0 3
Distance ( 0 - 4 ) : 3
# Path between 0 and 4 : 0 4
Distance ( 1 - 2 ) : 3
# Path between 1 and 2 : 1 2
Distance ( 1 - 3 ) : 1
# Path between 1 and 3 : 1 2 3
Distance ( 1 - 4 ) : 2
# Path between 1 and 4 : 1 2 3 4
Distance ( 2 - 3 ) : -2
# Path between 2 and 3 : 2 3
Distance ( 2 - 4 ) : -1
# Path between 2 and 4 : 2 3 4
Distance ( 3 - 4 ) : 1
# Path between 3 and 4 : 3 4
© 2019-2026 Algotree.org | All rights reserved.
This content is provided for educational purposes. Feel free to learn, practice, and share knowledge.
For questions or contributions, visit algotree.org
"The best error message is the one that never shows up. - Thomas Fuchs"