前置技能
算法简介
求最短路的算法之一,类似于Dijkstra算法,对于每一个点集中的点v,逐步减少起点s到v的最短路长度的估计值,知道达到其最短路径值。同时,Bellman-ford算法还会返回一个bool类型的值如果不存在从s可达到的负权回路就返回true,否则false,这样就能够在存在负权边的情况下解决单源最短路的问题,这点上比Dijkstra算法要优。由于该算法更多的是对边进行操作,因此能更高效地解决稀疏图的最短路问题。算法复杂度Θ(V*E)。
算法流程
- 初始化dist为无穷大(只有原点初始化为0)。
- 利用前向星存图。
- 进行循环,遍历所有边,进行松弛计算。
- 遍历中途的所有边,判断是否存在dist[v]>dist[u]+w[u][v],如果有则返回false,表示从原点出发存在可达的负权回路。
主要代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| bool Bellman_ford(int s) { int tt; for(int i=1; i<=n; i++) dist[i]=Inf; dist[s]=0; for(int i=1; i<=n-1; i++) for(int j=1; j<=n; j++) { if(dist[j]==Inf) continue; for(int k=head[j]; k+1; k=nxt[k]) { tt=to[k]; if(w[k]!=Inf&&dist[tt]>dist[j]+w[k]) dist[tt]=dist[j]+w[k]; } } for(int j=1; j<=n; j++) { if(dist[j]==Inf) continue; for(int k=head[j]; k+1; k=nxt[k]) { tt=to[k]; if(w[k]!=Inf&&dist[tt]>dist[j]+w[k]) return 0; } } return 1; }
|