续上章Dijkstra中(负权回路影响单源最短路径的计算):
在某些单源最短路径问题中,可能存在权为负的边。如果图G(V,E)不包含由源s可达的负权回路,则对所有v∈Vs,最短路径的权的定义&(s,v)依然正确,即使它是一个负值也是如此。但如果存在一个从s可达的负权回路,最短路径的定义就不能成立了。从s到该回路上的节点不存在最短路径,因为我们总可以顺着找出的“最短”路径再穿过负权回路,从而获得一个权值更小的路径,因此如果从s到v的某路径中存在一个负权回路,我们定义&(s,v)=-∞。
解决办法:Bellman-Ford算法
Bellman-Ford算法能在更一般的情况下解决单源点最短路径问题,在该算法中边的权可以为负。Bellman-Ford算法同样运用了松弛技术,对每一节点v∈V,逐步减小从源s到v的最短路长估计d[v]直至其达到实际最短路径的权&(s,v),如果图中存在负权回路,算法将会报告最短路径不存在。算法时间O(VE)。
Func Bellman_Ford(G,w,s):boolean;
{initiallze_single_source(G,s);
for i:=1 to |V|-1 do
for each(u,v)∈E do relax(u,v,w);
for each(u,v)∈E do
if d[v]>d[u]+w(u,v) then exit(false);
exit(true);
}
Bellman-Ford算法的思想基于以下事实:两点间如果有最短路径,那么每个节点最多经过一次。也就是说,这条路不超过n-1条边。如果一个节点经过了两次,那么就是走了一个圈。如果这个圈的权为正,显然不划算;如果是负圈,那么最短路径不存在。如果是零圈,去掉不影响最优值。