【原创】求最短路径-Bellman-Ford算法
2017-05-15 13:59
211 查看
Bellman-Ford算法
事先吐槽:几十年前的坑了!赶紧填完赶紧轻松引子
有这样一类题,它要求你从某个点出发,到某个为止走过的最短路径。很早很早以前,我们学习了弗洛伊德算法与迪杰斯塔拉算法。现在我们再来看看与前两种完全不同的做法。
算法原理与流程
Bellman-Ford算法的流程如下:在图G(V, E)(V为点集,E为边集),取一源点s,数组Dis[i]记录从源点s到顶点i的路径长度,初始化Dis全清∞,Dis[s]为0;
以下操作循环执行至多n-1次,n为顶点数:
对于每一条边e(u, v),如果Dis[u] + w(u, v) < Dis[v],则令Dis[v] = Dis[u]+w(u, v)。w(u, v)为边e(u,v)的权值;
如果对Dis
没有被更新,说明最短路径已经查找完毕,或者图不连通,则跳出循环。否则执行下次循环。
简单来讲,就是不停的枚举边,看能不能枚举出一条最短路径。
检测负环路
如果图中存在负环路,dijk会不停打转,Floyd理都不会理,那么Bellman-Ford呢?为了检测图中是否存在负环路,即权值之和小于0的环路。对于每一条边e(u, v),如果存在Dis[u] + w(u, v) < Dis[v]的边,则图中存在负环路,即是说该图无法求出单源最短路径。否则数组Dis
中记录的就是源点s到各顶点的最短路径长度。
时间复杂度
由上,Bellman-Ford算法的时间复杂度为O(V*E),适合于稀疏图。代码实现
#include<iostream> #include<cstdio> using namespace std; #define MAX 0x7fffffff #define N 1010 int nodenum, edgenum, original; //点,边,起点 struct Edge //边 { int u, v; int cost; }Edge; Edge edge ; int dis , pre ; bool Bellman_Ford() { for(int i = 1; i <= nodenum; ++i) //初始化 dis[i] = (i == original ? 0 : MAX); for(int i = 1; i <= nodenum - 1; ++i) for(int j = 1; j <= edgenum; ++j) { if(dis[edge[j].v] > dis[edge[j].u] + edge[j].cost) //松弛 { dis[edge[j].v] = dis[edge[j].u] + edge[j].cost; pre[edge[j].v] = edge[j].u; } } bool flag = 1; //判断是否含有负权回路 for(int i = 1; i <= edgenum; ++i) if(dis[edge[i].v] > dis[edge[i].u] + edge[i].cost) { flag = 0; break; } return flag; } void print_path(int root) //打印最短路的路径(反向) { while(root != pre[root]) //前驱 { printf("%d-->", root); root = pre[root]; } if(root == pre[root]) printf("%d\n", root); } int main() { scanf("%d%d%d", &nodenum, &edgenum, &original); pre[original] = original; for(int i = 1; i <= edgenum; ++i) { scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].cost); } if(Bellman_Ford()) for(int i = 1; i <= nodenum; ++i) //每个点最短路 { printf("%d\n", dis[i]); printf("Path:"); print_path(i); } else printf("have negative circle\n"); return 0; }
代码转自:http://blog.csdn.net/niushuai666/article/details/6791765
相关文章推荐
- Bellman-Ford算法:计算单源最短路径
- 最短路径——Bellman_Ford算法
- 2011.11.3 poj1860 Currency Exchange 单源最短路径 Bellman-Ford算法 解题报告
- 从零开始学算法(八)最短路径之Bellman-Ford算法的队列优化以及几种最短路径算法对比
- 【图】最短路径Bellman-Ford算法
- 从零开始学算法(七)最短路径之Bellman-Ford算法
- 图算法 单源最短路径 Bellman_Ford算法(边权值为负情况)
- 单源最短路径--Bellman-Ford算法及SPFA
- 最短路径(Floyd算法和Dijkstra算法和Bellman-Ford算法)
- 单源最短路径问题(Bellman-Ford算法)
- 最短路径(Bellman-Ford算法)
- 单源最短路径算法之Bellman-Ford算法
- Bellman-ford算法 实现源点最短路径 允许路径中有负权值
- 【算法】Bellman-Ford算法(单源最短路径问题)(判断负圈)
- 单源最短路径--Dijkstra算法&Bellman_Ford算法
- 【最短路径】:Dijkstra算法、SPFA算法、Bellman-Ford算法和Floyd-Warshall算法
- BellMan-Ford算法--寻找最短路径
- 含有负边的图的最短路径(Bellman_ford算法)
- 经典算法之图的最短路径(二):Bellman_Ford算法
- [图论]Bellman-Ford算法求解最短路径问题(含有负权重)