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) {
	u.resize(m + n, n), v.resize(m + n), w.resize(m + n, 0);
	std::ranges::iota(v | std::views::drop(m), 0);
 
	auto h = bellman_ford(n + 1, m + n, u, v, w, n);
 
	u.resize(m), v.resize(m), w.resize(m);
	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;
}