Johnson’s 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, or

  • time and space.

Tip

This problem can also be solved by the Floyd-Warshall Algorithm in time and space.

Tip

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

Algorithm

Let denote the length of the shortest path between and in graph .

  1. Let be a new vertex, and let .

  2. Apply the Bellman-Ford Algorithm to find for each vertex in .

Lemma

Let , then

  1. Let , then applying the lemma yields that is a directed graph with non-negative edge weights.
  2. Apply Dijkstra’s Algorithm times to find for each pair of vertices and in .

Lemma

  1. Apply the lemma to find .

This algorithm solves the problem in

  • time and space, or

  • time and space.

std::vector<std::vector<int>> johnson(int n, int m, std::vector<int> u, std::vector<int> v, std::vector<int> w) {
	for (int i = 0; i < n; i++) {
		u.push_back(n);
		v.push_back(i);
		w.push_back(0);
	}
 
	auto h = bellman_ford(n, m, u, v, w, n);
	for (int i = 0; i < m; i++) {
		w[i] += h[u[i]] - h[v[i]];
	}
 
	std::vector dist(n, std::vector<int>(n));
	for (int i = 0; i < n; i++) {
		dist[i] = dijkstra(n, m, u, v, w, i);
		for (int j = 0; j < n; j++) {
			dist[i][j] -= h[i] - h[j];
		}
	}
	return dist;
}