讲解SPFA使用的例题:

Problem Description
在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时
候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?
Input
输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在
地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=
C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。
输入保证至少存在1条商店到赛场的路线。
Output
对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间
Sample Input
2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0
Sample Output
3
2

可以看我之前总结的几个最短路径算法:
算法学习:最短路径
也是同样的例题。

对队列处理Bellman算法可以很好地优化,这种方法叫做SPFA,SPFA的效率很高,在算法竞赛中的应用很广泛。

Bellman算法有很多低效或无效的操作。分析Bellman算法,其核心部分是在每一轮操作中更新所有结点到起点s的最短距离。计算和调整一个结点u到s的最短距离后,如果紧接着调整u的邻居结点,这些邻居肯定有新的计算结果;而如果漫无目的地计算不与u相邻的结点,很可能毫无变化,所以这些操作是抵消的。

因此,在计算结点u之后,下一步只计算和调整它的邻居,这样能加快收敛的过程。这些步骤可以用队列进行操作,这就是SPFA。

SPFA很像BFS:
(1)起点s入队,计算它所有邻居到s的最短距离(当前最短距离,不是全局最短距离)。把s出队,状态有更新的邻居入队,没更新的不入队。也就是说,队列中都是状态有变化的点,只有这些结点才会影响最短路径的计算。
(2)现在队列的头部是s的一个邻居u。弹出u,更新其所有邻居的状态,把其中有状态变化的邻居入队列。
(3)这里有一个问题,弹出u之后,在后面的计算中u可能会再次更新状态。所以,u可能需要重新入队列。这一点很容易做到:在处理一个新的结点v时,它的邻居可能就是以前处理过的u,如果u的状态变化了,把u重新加入队列就行了。
(4)继续以上过程,直到队列为空。这也意味着所有结点的状态都不再更新。最后状态就是到起点s的最短路径。

基于邻接表的SPFA
在这个程序中,存图最合适的方法是邻接表。上面的步骤(2)是更新u的所有邻居结点的状态,而邻接表可以很快地检索一个结点的所有邻居,正符合算法的需要。
代码如下:

#include<bits/stdc++.h>
using namespace std;
const int INF=1e6;
const int NUM=105;
struct edge{int from,to,w;edge(int a,int b,int c){from=a;to=b;w=c;}
};
vector<edge>e[NUM];
int n,m;
int pre[NUM];
void print_path(int s,int t){;
}
int spfa(int s){int dis[NUM];bool inq[NUM];int Neg[NUM];memset(Neg,0,sizeof(Neg));Neg[s]=1;for(int i=1;i<=n;++i)dis[i]=INF,inq[i]=false;dis[s]=0,inq[s]=true;queue<int>Q;Q.push(s);while(!Q.empty()){int u=Q.front();Q.pop();inq[u]=false;for(int i=0;i<e[u].size();++i){int v=e[u][i].to,w=e[u][i].w;if(dis[u]+w<dis[v]){dis[v]=dis[u]+w;pre[v]=u;if(!inq[v]){inq[v]=true;Q.push(v);Neg[v]++;if(Neg[v]>n)return 1;}}}}printf("%d\n",dis[n]);return 0;
}
int main(){while(~scanf("%d%d",&n,&m)){if(!n&&!m)return 0;for(int i=1;i<=n;++i)e[i].clear();while(m--){int a,b,c;scanf("%d%d%d",&a,&b,&c);e[a].push_back(edge(a,b,c));e[b].push_back(edge(b,a,c));}spfa(1);}
}

算法学习:最短路径SPFA算法相关推荐

  1. Surf算法学习心得(一)——算法原理

    Surf算法学习心得(一)--算法原理 写在前面的话: Surf算法是对Sift算法的一种改进,主要是在算法的执行效率上,比Sift算法来讲运行更快!由于我也是初学者,刚刚才开始研究这个算法,然而网上 ...

  2. 算法学习四:算法性能分析理论基础——函数增长与渐进分析

    算法学习四:算法性能分析理论基础--函数增长与渐进分析 在算法性能分析过程中,特别是在算法运行效率分析中,我们经常使用渐渐分析法,它使我们在分析算法性能时不必纠结于不同硬件平台的差异性,着重考虑算法的 ...

  3. 第十九章 Bellman-Ford算法(由SPFA算法逆推BF,独特解读,超级详细)

    第十九章 Bellman-Ford算法 一.SPFA算法回顾: 二.Bellman-Ford算法 1.算法推导: 1.算法模板: 三.例题: 1.问题: 2.模板: 3.分析: 一.SPFA算法回顾: ...

  4. 最短路径——SPFA算法(蓝桥杯试题集)

    *对于本题的floyd题解请跳转:http://blog.csdn.net/sm9sun/article/details/53285870 题目链接: http://lx.lanqiao.cn/pro ...

  5. 遍历所有点的最短路径python_图遍历算法之最短路径Dijkstra算法

    一.最短路径问题(shortest path problem) 最短路径问题是图论研究中一个经典算法问题,旨在寻找图中两节点或单个节点到其他节点之间的最短路径.根据问题的不同,算法的具体形式包括: 确 ...

  6. 【算法学习】贪心算法

    参考算导第三版第16章 贪心算法 文章目录 1. 活动选择问题 1.1 活动选择问题的最优子结构 1.2 贪心选择 1.3 递归贪心算法 1.4 迭代贪心算法 2. 贪心算法原理 2.1 贪心选择性质 ...

  7. floyd算法_最短路径的算法:Floyd算法

    点击箭头处"蓝色字",关注我们哦!! 算法 最短路径的算法-Floyd算法 ● ○ ● Shortest Path Algorithm - Floyd Algorithm ● ○ ...

  8. 令人拍案叫绝的算法学习网站新手算法入门到精通,算法面试冲刺资料这里都有

    (9月已更)学算法认准这6个网站就够了! 写在前面:作为ACM铜牌选手,从FB到腾讯,从事算法&java岗位工作也是5年有余.在工作中接触到了很多同学,在算法学习和算法面试这件事上我还是很有发 ...

  9. 算法学习之模拟退火算法路径规划(python代码实现)

    模拟退火算法路径规划(python代码实现) 一.引言 二.算法介绍以及伪代码 1.算法通俗介绍 2.路径规划算法伪代码 三.算法流程及代码实现 1.地图创建 2.初始化路径 小结 3.计算适应度值 ...

  10. 令人拍案叫绝的算法学习网站,算法入门到精通,算法面试冲刺资料这里都有

    前言 作为ACM铜牌选手,从FB到腾讯,从事算法&java岗位工作也是5年有余.在工作中接触到了很多同学,在算法学习和算法面试这件事上我还是很有发言权的. 今天就跟想学算法的同学分享一下我私藏 ...

最新文章

  1. 【PL/SQL】--导出oracle单表数据--drp204
  2. 科大讯飞AIUI(1)
  3. linux内核镜像解压,解压内核镜像
  4. linux操作系统cp命令
  5. 朋友公司招聘用的一套C#基础面试题,10个码农8个错2个蒙,我也跳坑了…
  6. MySQL各个版本区别
  7. IT女性必备——5个方法变身小腰精
  8. pytorch的索引与切片
  9. spring底层原理
  10. 安卓 java 视频_安卓实战项目-动态桌面-rxjava实现搜索本地所有视频
  11. 大数据开发笔记(二):Yarn分布式集群操作系统
  12. CentOS清除用户登录记录和命令历史方法
  13. Vmware 安装安卓x86虚拟机并运行APP
  14. 【图片】 3D打印的一些小东西 暗黑
  15. Kali 利用setoolkit制作钓鱼网站
  16. 常用软件安装及破解——IntelliJ IDEA
  17. 探讨!自媒体的推荐机制提高百家号阅读收益方法!
  18. Python自动检查哪位学生未提交作业
  19. 转:(记录)C语言中的itoa()函数的用法解析
  20. (8)Artemis检测(僵尸连接、慢消费者、代理异常)

热门文章

  1. angular 表单操作
  2. NGUI组件参数总结
  3. 搭建企业级Docker Registry -- Harbor
  4. 微软Windows系统命令和Sysinternals系列工具
  5. 叶脊网络拓扑(leaf-spine)
  6. [转]JS弹出div和关闭
  7. C/C++ map函数统计每个字母出现的次数
  8. 浏览器中调用Linux程序,一个可以使用浏览器通过ssh连接linux的程序
  9. 列出所有内核_Windows系统内核溢出漏洞提权
  10. python实用宝典_python 5个实用的技巧