Given a graph of V vertices numbered from 0 to V-1. Find the shortest distances between every pair of vertices in a given edge-weighted directed graph. The graph is represented as an adjacency matrix of size n x n. Matrix[i][j] denotes the weight of the edge from i to j. If matrix[i][j]=-1, it means there is no edge from i to j.
Input: matrix = [[0, 2, -1, -1],[1, 0, 3, -1],[-1, -1, 0, 1],[3, 5, 4, 0]]
Output: [[0, 2, 5, 6], [1, 0, 3, 4], [4, 6, 0, 1], [3, 5, 4, 0]]
Explanation: matrix[0][0] is storing the distance from vertex 0 to vertex 0, the distance from vertex 0 to vertex 1 is 2 and so on.
Input: matrix = [[0,25],[-1,0]]
Output: [[0, 25],[-1, 0]]
Explanation: The matrix already contains the shortest distance.
Input: matrix = [[0,1,43],[1,0,6],[-1,-1,0]]
In the problem, it is required to find the shortest distance between every pair of vertices which can be seen as finding the shortest distance of every node from all nodes (multiple sources). There are already algorithms namely Dijkstra's Algorithm and Bellman Ford Algorithm but they are single-source shortest path algorithms. But here since multiple sources are considered, the FLoyd Warshall algorithm will come into picture.
The Floyd Warshall algorithm is a multi-source shortest path algorithm and it helps to detect negative cycles (a cycle where sum of all weights is negative) as well. The shortest path between node u and v means the path(from u to v) for which the sum of the edge weights is minimum.
The Floyd Warshall algorithm is nothing but the brute force approach of checking every possible path from node u to node v (via some node k) to figure out the shortest path from node u to node v.
dist[s][d] = min(all the paths from source to destination)
dist[s][d] = min(9, 4, 14, 8, 6)
dist[s][d] = 4. (Via node 2)
.
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
/* Function to find the shortest distance
between every pair of vertices. */
void shortest_distance(vector<vector<int>> &matrix){
// Getting the number of nodes
int n = matrix.size();
// For each intermediate node k
for(int k=0; k<n; k++) {
// Check for every (i, j) pair of nodes
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
/* If k is not an intermediate
node, skip the iteration */
if(matrix[i][k] == -1 ||
matrix[k][j] == -1)
continue;
/* If no direct edge from
i to v is present */
if(matrix[i][j] == -1) {
// Update the distance
matrix[i][j] =
matrix[i][k] + matrix[k][j];
}
/* Else update the distance to
minimum of both paths */
else {
matrix[i][j] =
min(matrix[i][j] ,
matrix[i][k] + matrix[k][j]
);
}
}
}
}
}
};
int main() {
vector<vector<int>> matrix ={
{0, 2, -1, -1},
{1, 0, 3, -1},
{-1, -1, 0, -1},
{3, 5, 4, 0}
};
/* Creating an instance of
Solution class */
Solution sol;
/* Function to find the shortest distance
between every pair of vertices. */
sol.shortest_distance(matrix);
// Output
int n = matrix.size();
cout << "The shortest distance matrix is:\n";
for(int i=0; i < n; i++) {
for(int j=0; j < n; j++) {
cout << matrix[i][j] << " ";
}
cout << endl;
}
return 0;
}
import java.util.Arrays;
class Solution {
/* Function to find the shortest distance
between every pair of vertices. */
public void shortest_distance(int[][] matrix) {
// Getting the number of nodes
int n = matrix.length;
// For each intermediate node k
for (int k = 0; k < n; k++) {
// Check for every (i, j) pair of nodes
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
/* If k is not an intermediate
node, skip the iteration */
if (matrix[i][k] == -1 || matrix[k][j] == -1)
continue;
/* If no direct edge from
i to v is present */
if (matrix[i][j] == -1) {
// Update the distance
matrix[i][j] = matrix[i][k] + matrix[k][j];
}
/* Else update the distance to
minimum of both paths */
else {
matrix[i][j] = Math.min(matrix[i][j], matrix[i][k] + matrix[k][j]);
}
}
}
}
}
public static void main(String[] args) {
int[][] matrix = {
{0, 2, -1, -1},
{1, 0, 3, -1},
{-1, -1, 0, -1},
{3, 5, 4, 0}
};
/* Creating an instance of
Solution class */
Solution sol = new Solution();
/* Function to find the shortest distance
between every pair of vertices. */
sol.shortest_distance(matrix);
// Output
int n = matrix.length;
System.out.println("The shortest distance matrix is:");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
}
}
class Solution:
# Function to find the shortest distance
# between every pair of vertices.
def shortest_distance(self, matrix):
# Getting the number of nodes
n = len(matrix)
# For each intermediate node k
for k in range(n):
# Check for every (i, j) pair of nodes
for i in range(n):
for j in range(n):
# If k is not an intermediate
# node, skip the iteration
if matrix[i][k] == -1 or matrix[k][j] == -1:
continue
# If no direct edge from
# i to v is present
if matrix[i][j] == -1:
# Update the distance
matrix[i][j] = matrix[i][k] + matrix[k][j]
# Else update the distance to
# minimum of both paths
else:
matrix[i][j] = min(matrix[i][j], matrix[i][k] + matrix[k][j])
# Example usage
matrix = [
[0, 2, -1, -1],
[1, 0, 3, -1],
[-1, -1, 0, -1],
[3, 5, 4, 0]
]
# Creating an instance of
# Solution class
sol = Solution()
# Function to find the shortest distance
# between every pair of vertices.
sol.shortest_distance(matrix)
# Output
print("The shortest distance matrix is:")
for row in matrix:
print(" ".join(map(str, row)))
class Solution {
/* Function to find the shortest distance
between every pair of vertices. */
shortest_distance(matrix) {
// Getting the number of nodes
let n = matrix.length;
// For each intermediate node k
for (let k = 0; k < n; k++) {
// Check for every (i, j) pair of nodes
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
/* If k is not an intermediate
node, skip the iteration */
if (matrix[i][k] === -1 || matrix[k][j] === -1)
continue;
/* If no direct edge from
i to v is present */
if (matrix[i][j] === -1) {
// Update the distance
matrix[i][j] = matrix[i][k] + matrix[k][j];
}
/* Else update the distance to
minimum of both paths */
else {
matrix[i][j] =
Math.min(matrix[i][j], matrix[i][k] + matrix[k][j]);
}
}
}
}
}
}
// Example usage
let matrix = [
[0, 2, -1, -1],
[1, 0, 3, -1],
[-1, -1, 0, -1],
[3, 5, 4, 0]
];
// Creating an instance of
// Solution class
let sol = new Solution();
// Function to find the shortest distance
// between every pair of vertices.
sol.shortest_distance(matrix);
// Output
console.log("The shortest distance matrix is:");
matrix.forEach(row => console.log(row.join(" ")));
Time Complexity: O(N3) (where N repesents the number of nodes in graph) Because of three nested loops.
Space Complexity: O(N2) The algorithm uses a space of O(N2) to store shortest distance between every pair of nodes possible.
Q: Why use Floyd-Warshall instead of Dijkstra’s Algorithm?
A: Floyd-Warshall computes all-pairs shortest paths in O(V³), whereas Dijkstra’s needs O(V² log V + VE), making it inefficient for dense graphs.
Q: How does Floyd-Warshall compare to Bellman-Ford?
A: Floyd-Warshall (O(V³)) is ideal for dense graphs. Bellman-Ford (O(V²E)) is more useful for sparse graphs with negative weights.
Q: What if we needed to reconstruct the shortest paths, not just distances?
A: Maintain a parent matrix (next[][]), updating it during relaxation to track the intermediate vertices.
Q: What if the graph was very large (V > 10^4)?
A: Floyd-Warshall is infeasible; instead, use Johnson’s Algorithm (O(V² log V + VE)), which combines Dijkstra’s and Bellman-Ford for better efficiency.