Here we discuss the Bellman Ford algorithm for computing shortest path or negative cycle in an undirected weighted graph that contains negative edges.
Recall the Dijkstra algorithm bases on the induction of the number of vertices. The Bellman Ford algorithm, on the other hand, bases on the induction of the number of edges of the shortest path.
Let be the shortest path between and . If we finds the shortest , then we can easily find the path . To this end, we define dist[v] the distance from source node to vertex .
std::vector<int> dist(n, INT_MAX);
std::vector<int> pred(n, 0);
dist[s] = 0;
for(int i = 0; i < n - 1; ++i) {
for each edge (u, v) {
if(dist[u] + w(u, v) < dist[v]) {
dist[v] = dist[u] + w(u, v);
pred[v] = u;
}
}
}
If the graph does not contain a negative cycle, the above code compute the shortest path correctly. On the other hand, to check the existence of a negative, we could execute an additional iteration after the above code
bool check_negative_cycle() {
for each edge (u, v) {
if(dist[u] + w(u, v) < dist[v]) {
dist[v] = dist[u] + w(u, v);
pred[v] = u;
return true;
}
}
return false;
}
The correctness can be verified as follows: if the graph does not contain negative cycle, the any shortest path contains at most -th edges. The value of should not change in this -th iteration.
To return a negative cycle, when we find an edge such that (in this -th iteration), we can trace the predecessor of until we encounter a cycle. Notice that this cycle may not necessarily contains . But we claim that this cycle must be negative.
Theorem
Let be the cycle we found, such that and . WLOG, let be the vertex whose value is updated latest among . It holds that
It follows that , which implies that .