图论算法----最短路径SPFA算法详解
来源:互联网 发布:sqlserver backup log 编辑:程序博客网 时间:2024/05/21 14:07
一、题目描述
SPFA算法
题目描述
有向图的单源点最短路径问题。源点编号为1,终点编号为n。
输入
第1行:2个空格分开的整数n(2<=n<=5000)和m(10<=m<=500000),分别表示图的顶点数和边数。
第2..m+1行:每行3个空格分开的整数i,j, w。i表示一条边的起点,j表示终点, w表示权值。
输出
第1行:1个整数,表示最小距离
样例输入
样例1:4 71 2 681 3 191 4 662 3 233 4 653 2 574 1 68样例2:3 31 2 -72 3 43 1 2
样例输出
样例1:66样例2:No Solution
二、算法分析
(在看算法分析时,请保证自己对题目已经十分熟悉)
(该算法比较复杂,需要读者具有一定的基础,了解队列的一些用法)
这种题目是典型的最短路径问题,可以用许多算法来解决,但是看了数据范围之后......只有SPFA能够解决。
知道了用SPFA算法, 那我们就来看看SPFA的思路
SPFA是Bellman-Ford的升级版,因为Bellman-Ford里有许多不必要的计算,所以SPFA就利用队列来进行了时间复杂度的优化。
SPFA算法全过程:
1、将起点加入队列,while循环开始。
2、从队列中取出一个元素,for循环开始。
3、用它的最短路径来更新与它相邻的点最短路径,如果有更新成功的,就将其入队
4、for循环结束
5、当队列为空时,while循环结束。
时间复杂度为O(kE),k为常数,大约为2,E为边数,一个接近完美的算法。
算法的总体结构有点像BFS(广搜),但是SPFA中不会判重,就是一个点有可能会多次入队。
看起来SPFA的思路很简单,但是实践起来就不同了。
三、题目分析
(在看题目分析时,请大家做好心理准备)
看完题目后,相信大家对程序的框架已经搭好了,大概是这样的:
初始化+SPFA+负权回路判断
但是仔细一看,这些都是难点。
1、初始化:
(1)、将dis数组清为最大值,dis[1]=0;
(2)、将输入的边进行排序(写cmp函数)
(3)、计算每一个点的出边数和对应的起始位置,为SPFA做准备
2、SPFA
(1)、取出一个点
(2)、判断是否有出边
(3)、进行连接点最短路径的更新
3、负权回路判断
这个比较简单,用一个pd数组,一个点入队一次就pd[该点编号]++,
如果超过了pd[该点编号]总点数,就输出“No Solution”。
AC代码:
#include<cstdio>#include<algorithm>#include<cstring>#include<queue>using namespace std;queue <int > q;int dis[5005],out[5005][2],n,m,pd[5005];struct node{ int cd,s,t;}w[500005];bool cmp(node a,node b){ if(a.s<b.s) return 1; else if(a.s>b.s) return 0; else if(a.t<b.t) return 1; else return 0;}int main(){ int i,u; scanf("%d%d",&n,&m); memset(dis,1,sizeof(dis)); for(i=1;i<=m;i++){ scanf("%d%d%d",&w[i].s,&w[i].t,&w[i].cd); out[w[i].s][1]++; } sort(w+1,w+n+1,cmp); q.push(1); dis[1]=0; out[1][0]=1; for(i=2;i<=n;i++) out[i][0]=out[i-1][0]+out[i-1][1]; while(!q.empty()){//SPFA u=q.front(); q.pop(); if(out[u][1]!=0){ for(i=out[u][0];i<=out[u][0]+out[u][1]-1;i++){ if(dis[u]+w[i].cd<dis[w[i].t]){ dis[w[i].t]=dis[u]+w[i].cd; q.push(w[i].t); pd[w[i].t]++;//pd if(pd[w[i].t]>n){ printf("No Solution"); return 0; } } } } } printf("%d",dis[n]);}
- 图论算法----最短路径SPFA算法详解
- 最短路径算法---SPFA
- 最短路径----SPFA算法
- 【最短路径】SPFA算法
- SPFA算法【最短路径】
- 最短路径SPFA算法
- 最短路径算法之SPFA算法
- POJ_2394_最短路径---SPFA算法
- 最短路径之SPFA算法
- 最短路径 之 SPFA算法
- 最短路径的SPFA算法
- 【转载】最短路径之SPFA算法
- 最短路径问题 SPFA算法
- 最短路径 之 SPFA算法
- 最短路径——SPFA算法
- 最短路径之spfa算法
- 最短路径之Spfa算法
- 最短路径 之 SPFA算法
- Activity不能设置背景
- 如何通过 模糊搜索,取得完整关键词!
- Ubuntu下OpenVPN客户端配置教程
- XUtils 3 如何设置http请求头啊
- Percent 库
- 图论算法----最短路径SPFA算法详解
- cocos2dx 帧动画使用方法备忘
- PhoneGap(Cordova)
- 成员变量设值
- H标签
- eclipse开发中常见问题
- 在ADB中ping可用,但在程序里调用ping总是报错“permission denied”
- BroadcastReceiver的onReceive不执行
- TabLayout和ViewPager实现滑动片段