The Floyd-Warshall Algorithm is an algorithm that computes the length of the shortest path between every pair of vertices in a directed graph with edge weights and no negative cycles in time and space.

Tip

This problem can also be solved by the Bellman-Ford Algorithm in time and space.

Tip

This problem can also be solved by Johnson’s Algorithm in

  • time and space, or

  • time and space.

Algorithm 0

Lemma

Let , and let denote the length of the shortest path from to that only passes through (excluding the endpoints) vertices . Then

Lemma

Let denote the length of the shortest path from to , then

Applying the lemmas to find and yields an algorithm that solves the problem in time and space.

std::vector<std::vector<int>> floyd_warshall(int n, int m, const std::vector<int> &u, const std::vector<int> &v, const std::vector<int> &w) {
	std::vector dist(n + 1, std::vector(n, std::vector(n, inf)));
	for (int i = 0; i < m; i++) {
		dist[0][u[i]][v[i]] = std::min(dist[0][u[i]][v[i]], w[i]);
	}
	for (int k = 0; k < n; k++) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				dist[k + 1][i][j] = std::min(dist[k][i][j], dist[k][i][k] + dist[k][k][j]);
			}
		}
	}
	return dist[n];
}

Algorithm 1

Lemma

Applying the lemma yields that the first dimension can be ignored.

Based on Algorithm 0, ignoring the first dimension yields an algorithm that solves the problem in time and space.

std::vector<std::vector<int>> floyd_warshall(int n, int m, const std::vector<int> &u, const std::vector<int> &v, const std::vector<int> &w) {
	std::vector dist(n, std::vector(n, inf));
	for (int i = 0; i < m; i++) {
		dist[u[i]][v[i]] = std::min(dist[u[i]][v[i]], w[i]);
	}
	for (int k = 0; k < n; k++) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				dist[i][j] = std::min(dist[i][j], dist[i][k] + dist[k][j]);
			}
		}
	}
	return dist;
}