单源最短路径:给定一个图,和一个源顶点src,找到从src到其它所有所有顶点的最短路径,图中可能含有负权值的边。
Dijksra的算法是一个贪婪算法,时间复杂度是O(VLogV)(使用最小堆)。但是迪杰斯特拉算法在有负权值边的图中不适用,
Bellman-Ford适合这样的图。在网络路由中,该算法会被用作距离向量路由算法。
Bellman-Ford也比迪杰斯特拉算法更简单和同时也适用于分布式系统。但Bellman-Ford的时间复杂度是O(VE),E为边的个数,这要比迪杰斯特拉算法慢。
算法描述:
输入:图 和 源顶点src
输出:从src到所有顶点的最短距离。如果有负权回路(不是负权值的边),则不计算该最短距离,没有意义,因为可以穿越负权回路任意次,则最终为负无穷。
算法步骤:
1.初始化:将源节点到其他所有顶点的距离初始化为无穷,到自身距离初始化为0.
存放在构造的大小为|V|的dist[]数组中。 d[v] ← +∞, d[s] ←0;
2.计算最短距离。迭代求解:反复对边集E中的每条边进行松弛操作,使得顶点集V中的每个顶点
v的最短距离估计值逐步逼近其最短距离;(运行|v|-1次)
做法如下:
Do following |V|-1 times where |V| is the number of vertices in
given graph.
…..a) Do following for each edge u-v
………………If dist[v] > dist[u] + weight of edge uv, then update
dist[v]
………………….dist[v] = dist[u] + weight of edge uv
3.检验负权回路:判断边集E中的每一条边的两个端点是否收敛。如果存在未收敛的顶点,则算
法返回false,表明问题无解;否则算法返回true,并且从源点可达的顶点v的最短距离保存在
d[v]中。
做法如下:
Do following for each edge u-v
……If dist[v] > dist[u] + weight of edge uv, then “Graph contains
negative weight cycle”
The idea of step 3 is, step 2 guarantees shortest distances if graph
doesn’t contain negative weight cycle. If we iterate through all
edges one more time and