一、Bellman-Ford算法
1.算法原理:对于n个顶点的图,最坏情况下进行n-1轮对每条边的松弛操作一定可以得到最短路。
和松弛顺序无关,边权可以为负。
2.相比Dijkstra的优点为:负边权和负环可以用Bellman-Ford算法解决,但Dijkstra不可以有负边权
3.当图中有负环时,最短路为-∞
4.Bellman–Ford可以判断出图是否存在负环路,只需要在n-1次遍历后,再执行一次遍历,若还可以更新数据则说明存在负环路
5.算法代码:
bool BellmanFord(){
memset(dist,0x3f,sizeof(dist));
dist[v0]=0;
for(int k=1;k<=n-1;k++){
bool flag=false;
for(int i=1;i<=res;i++){//res 边的个数
Edge e=edges[i];
if(dist[e.from]<0x3f3f3f3f&&dist[e.to]>dist[e.from]+e.len){
dist[e.to]=dist[e.from]+edges[i].len;
flag=true;
}
}
if(!flag){
return true;
}
}
}
我们来画图理解一下
1.初始化
前节点 | 当前节点 | 与1的最短距离 |
---|---|---|
1 | 1 | 0 |
2 | ∞ | |
3 | ∞ | |
4 | ∞ | |
5 | ∞ |
2.
前节点 | 当前节点 | 与1的最短距离 |
---|---|---|
1 | 1 | 0 |
1 | 2 | -1 |
1 | 3 | 4 |