Bellman-Ford Algorithm
Bellman-Ford solves the single-source shortest paths problem on a weighted directed graph that may contain negative edges. Unlike Dijkstra, it does not assume any sign restriction on the weights; in exchange, it runs in instead of . It also doubles as the standard certificate for the existence of a negative-weight cycle reachable from the source — if one exists, there is no well-defined shortest path, and the algorithm reports failure.
The idea is disarmingly simple: relax every edge times. Because any shortest path has at most edges (otherwise it would contain a repeated vertex, i.e. a cycle, which could be excised without increasing the weight), full passes are sufficient to propagate any finite shortest distance. A -th pass that still improves some distance witnesses a negative cycle.
The solve function takes [n, edges, source] with edges as
[u, v, w] triples on vertices , and returns the
distance array with 10**18 for unreachable vertices. If a negative
cycle is reachable from source, it returns [].
Codes
- Python
- C++
def solve(xs):
"""xs = [n, edges, source]. Return distances (10**18 for unreachable),
or [] if a negative cycle is reachable from source."""
n, edges, source = xs
INF = 10**18
dist = [INF] * n
dist[source] = 0
for _ in range(n - 1):
updated = False
for u, v, w in edges:
if dist[u] != INF and dist[u] + w < dist[v]:
dist[v] = dist[u] + w
updated = True
if not updated:
break
# One more pass: if anything still improves, there is a negative cycle
# reachable from source.
for u, v, w in edges:
if dist[u] != INF and dist[u] + w < dist[v]:
return []
return dist
#include <array>
#include <vector>
const long long INF = (long long)1e18;
std::vector<long long> bellman_ford(int n,
const std::vector<std::array<int, 3>>& edges, int source) {
std::vector<long long> dist(n, INF);
dist[source] = 0;
for (int i = 0; i < n - 1; ++i) {
bool updated = false;
for (auto& e : edges) {
int u = e[0], v = e[1], w = e[2];
if (dist[u] != INF && dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
updated = true;
}
}
if (!updated) break;
}
for (auto& e : edges) {
int u = e[0], v = e[1], w = e[2];
if (dist[u] != INF && dist[u] + w < dist[v]) return {}; // neg cycle
}
return dist;
}
Example
Description
Run time analysis
. Each of the passes relaxes all edges. The final negative-cycle check is another . The early-exit when a pass does no updates often makes the algorithm much faster on easy inputs but does not improve the worst case.
Space analysis
. The distance array is and the edge list is read as input, so no adjacency structure is required.
Proof of correctness
Let denote the length of the shortest -to- walk in the graph (taking the value if the graph has a negative cycle reachable from on every -to- path).
Claim. If the graph has no negative cycle reachable from , then after the -th relaxation pass the minimum weight of any -to- walk that uses at most edges.
Induction on . Base : and for , and the only walk with zero edges is the empty walk at itself.
Inductive step. Suppose the claim holds for , and consider a shortest -to- walk using at most edges. If uses fewer than edges, the inductive hypothesis already gives . Otherwise let be the predecessor of on , so the prefix of is an -to- walk of at most edges with weight . By induction, just before the -th pass. During the -th pass the algorithm relaxes and sets , so the claim holds after pass .
Because any simple shortest path has at most edges, and in the absence of a negative cycle we never improve by adding cycles, after passes for every vertex reachable from . Unreachable vertices stay at (here encoded as ).
Negative-cycle detection. If a negative cycle is reachable from , then for some edge on that cycle we have — the cycle can be traversed once more to strictly decrease the tentative distance of . So the -th pass will still relax some edge. Conversely, if the -th pass relaxes some edge, then there is a walk of more than edges improving on any -edge walk, which forces a cycle of negative total weight.
Extensions
Applications
References
- Cormen, Leiserson, Rivest, Stein. Introduction to Algorithms, 3rd ed., Chapter 24 (Single-Source Shortest Paths).
- Bellman, R. (1958). "On a routing problem." Quarterly of Applied Mathematics, 16(1), 87-90.
- cp-algorithms — Bellman-Ford