bellman-ford and SPFA
来源:互联网 发布:hp1005扫描软件 编辑:程序博客网 时间:2024/05/21 19:28
第一种算法bellman-ford算法
这段文字来自lrj书的截图
其中解释一下如果一个图是DAG如何用拓扑序来计算d[i];
因为无环图的话求一个顶点的最短路不用考虑这个顶点后面的点,所以就可以用拓扑序来用计算一个点后面的所有点的距离
一般情况
c被a更新一次最短路为3,最后被b更新最短路为2;
算法实现就是先用拓扑排序得到一个队列,再依次用队列中的顶点求其所有邻接点的最短路;复杂度是O(v+e)拓扑排序是v,求最短路是e。
如果不是DAG图
如果是DAG图,就不知道从哪儿开始更新,所以要遍历所有边来更新,直到最短路不再改变,从上面的DAG图我们可以知道,按照类似拓扑顺序的更新最短路是最快的,反之最慢这样最多就是外层循环V-1次。
复杂度O(v*e)
#include <iostream>#include<cstdio>using namespace std;const int N=1e3;const int M=1e3;const int INF=0x1ffff;int n,m;struct edge{ //存放边(起点,终点,弧(边)长)的结构体 int from,to,cost; void set(int a,int b,int c){ from=a;to=b;cost=c; }};edge e[M]; //边数组 int d[N]; //起点到每个其他顶点最短距离辅助数组int main(){ freopen("in.txt","r",stdin); cin>>n>>m; int a,b,c; for(int i=0;i<m;i++){ cin>>a>>b>>c; e[i].set(a,b,c); } for(int i=1;i<=n;i++){ d[i]=INF; } printf("输入x,y\n"); int x,y; cin>>x>>y; d[x]=0; //28行~这里是初始化,d[i]=INF,d[起点]=0; while(true){ //外层循环最多循环n-1次,在图为线性的时候取最大值 bool change=false; for(int i=0;i<m;i++){ //遍历所有边 edge ed=e[i]; if(d[ed.from]!=INF&&d[ed.to]>d[ed.from]+ed.cost){ //起点能到中间点,且中间点加入后距离变小 change=true; d[ed.to]=d[ed.from]+ed.cost; } } if(!change)break; } printf("the minidistance between %d and %d is %d\n",x,y,d[y]); return 0;}
如图,如果是1 2 3 4 四个点的话,顺序遍历一次边就结束了,逆序遍历的话,(3,4),(2,3)都无效,然后加入(1,2) 以此类推。
SPFA算法(摘抄)
先讲一下SPFA的大致思想
算法大致流程是用一个队列来进行维护。 初始时将源加入队列。 每次从队列中取出一个元素,并对所有与他相邻的点进行松弛,若某个相邻的点松弛成功,如果该点没有在队列中,则将其入队。 直到队列为空时算法结束。
判断有无负环:如果某个点进入队列的次数超过V次则存在负环(SPFA无法处理带负环的图)
SPFA算法有两个优化算法 SLF 和 LLL: SLF:Small Label First 策略,设要加入的节点是j,队首元素为i,若dist(j)<dist(i),则将j插入队首,否则插入队尾。 LLL:Large Label Last 策略,设队首元素为i,队列中所有dist值的平均值为x,若dist(i)>x则将i插入到队尾,查找下一元素,直到找到某一i使得dist(i)<=x,则将i出对进行松弛操作。 SLF 可使速度提高 15 ~ 20%;SLF + LLL 可提高约 50%。 在实际的应用中SPFA的算法时间效率不是很稳定,为了避免最坏情况的出现,通常使用效率更加稳定的Dijkstra算法。个人觉得LLL优化每次要求平均值,不太好,为了简单,我们可以之间用C++STL里面的优先队列来进行SLF优化
- bellman-ford and SPFA
- Bellman-Ford&SPFA算法
- Bellman-Ford || SPFA :Wormholes
- Bellman-ford Spfa hihocoder1903
- 松弛算法-->Bellman-Ford-->SPFA
- Bellman-ford和spfa算法
- HDU1874(Bellman-Ford,SPFA)
- Bellman-ford和spfa算法
- poj 3259 Bellman-ford + SPFA
- poj 3259 spfa + Bellman-Ford
- dijkstra与spfa(bellman-Ford)
- Bellman-Ford算法以及优化(SPFA)
- poj 3259 Wormholes(SPFA || Bellman-Ford)
- poj 3259 Wormholes【Bellman-Ford Vs SPFA】
- poj 3259 Wormholes SPFA // Bellman-ford
- Bellman-Ford算法 和 SPFA算法
- bellman-ford算法的优化spfa算法
- Bellman-ford算法学习与SPFA算法
- 不使用四则运算符实现两个数相加
- 如何开通 linux 防火墙
- UVA 839 天平
- 苹果开发者账号Apple ID如何进行资料修改?
- JVM系列二(虚拟机对象创建、布局、定位)
- bellman-ford and SPFA
- 用线程的方式控制并发
- Codeforces Beta Round #96 (Div. 1) C. Logo Turtle —— DP
- idea安装地址以及破解方法
- elasticsearch中的API
- caffe 学习之LayerParameter
- Javaweb简单博客系统-----(二)数据库建表
- XCode里遇到 #include <XXX.h>file not found的解决方案
- Python学习之旅-20