一:背景

SPFA(Shortest Path Faster Algorithm)算法,是西南交通大学段凡丁于 1994 年发表的,其在 Bellman-ford 算法的基础上加上一个队列优化,减少了冗余的松弛操作,是一种高效的最短路算法。

二:算法过程

设立一个队列用来保存待优化的顶点,优化时每次取出队首顶点 u,并且用 u 点当前的最短路径估计值dist[u]对与 u 点邻接的顶点 v 进行松弛操作,如果 v 点的最短路径估计值dist[v]可以更小,且 v 点不在当前的队列中,就将 v 点放入队尾。这样不断从队列中取出顶点来进行松弛操作,直至队列空为止。(所谓的松弛操作,简单来说,对于顶点 i,把dist[i]调整更小或更大。更多解释请参考百科:松弛操作)

而其检测负权回路的方法也很简单,如果某个点进入队列的次数大于等于 n,则存在负权回路,其中 n 为图的顶点数。

一个图文详解非常详细的博客:http://www.360doc.com/content/13/1208/22/14357424_335569176.shtml

比较简单的算法,容易理解。

#1093 : 最短路径·三:SPFA算法

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

万圣节的晚上,小Hi和小Ho在吃过晚饭之后,来到了一个巨大的鬼屋!

鬼屋中一共有N个地点,分别编号为1..N,这N个地点之间互相有一些道路连通,两个地点之间可能有多条道路连通,但是并不存在一条两端都是同一个地点的道路。

不过这个鬼屋虽然很大,但是其中的道路并不算多,所以小Hi还是希望能够知道从入口到出口的最短距离是多少?

提示:Super Programming Festival Algorithm。

输入

每个测试点(输入文件)有且仅有一组测试数据。

在一组测试数据中:

第1行为4个整数N、M、S、T,分别表示鬼屋中地点的个数和道路的条数,入口(也是一个地点)的编号,出口(同样也是一个地点)的编号。

接下来的M行,每行描述一条道路:其中的第i行为三个整数u_i, v_i, length_i,表明在编号为u_i的地点和编号为v_i的地点之间有一条长度为length_i的道路。

对于100%的数据,满足N<=10^5,M<=10^6, 1 <= length_i <= 10^3, 1 <= S, T <= N, 且S不等于T。

对于100%的数据,满足小Hi和小Ho总是有办法从入口通过地图上标注出来的道路到达出口。

输出

对于每组测试数据,输出一个整数Ans,表示那么小Hi和小Ho为了走出鬼屋至少要走的路程。

样例输入

5 10 3 5
1 2 997
2 3 505
3 4 118
4 5 54
3 5 480
3 4 796
5 2 794
2 5 146
5 4 604
2 5 63
样例输出
172
#include <bits/stdc++.h>
using namespace std;
const int AX = 1e5+666;
const int INF = 1234567;
int dis[AX];int n,m,s,t;
vector<int>vec[AX];
vector<int>wei[AX];
int vis[AX];
queue<int>que;
void SPFA(){memset(vis,0,sizeof(vis));for(int i=1;i<=n;i++){dis[i] = INF;}que.push(s);dis[s] = 0;vis[s] = 1;while(!que.empty()){int u = que.front();que.pop();vis[u] = 0;for(int i=0;i<vec[u].size();i++){if(wei[u][i] != INF){if(dis[u] + wei[u][i] < dis[vec[u][i]]){dis[vec[u][i]] = dis[u] + wei[u][i];if(!vis[vec[u][i]]){que.push(vec[u][i]);vis[vec[u][i]] = 1;}}}}}
} int main(){scanf("%d%d%d%d",&n,&m,&s,&t);int x,y,w;while(m--){scanf("%d%d%d",&x,&y,&w);vec[x].push_back(y);vec[y].push_back(x);wei[x].push_back(w);wei[y].push_back(w);}SPFA();printf("%d\n",dis[t]);return 0;
}
/**
*   别人的模板
* author 刘毅(Limer)
* date   2017-05-28
* mode   C++
*/
#include<iostream>
#include<queue>
#include<stack>
using namespace std;int matrix[100][100];  //邻接矩阵
bool visited[100];     //标记数组
int dist[100];         //源点到顶点i的最短距离
int path[100];         //记录最短路的路径
int enqueue_num[100];  //记录入队次数
int vertex_num;        //顶点数
int edge_num;          //边数
int source;            //源点bool SPFA()
{memset(visited, 0, sizeof(visited));memset(enqueue_num, 0, sizeof(enqueue_num));for (int i = 0; i < vertex_num; i++){dist[i] = INT_MAX;path[i] = source;}queue<int> Q;Q.push(source);dist[source] = 0;visited[source] = 1;enqueue_num[source]++;while (!Q.empty()){int u = Q.front();Q.pop();visited[u] = 0;for (int v = 0; v < vertex_num; v++){if (matrix[u][v] != INT_MAX)  //u与v直接邻接{if (dist[u] + matrix[u][v] < dist[v]){dist[v] = dist[u] + matrix[u][v];path[v] = u;if (!visited[v]){Q.push(v);enqueue_num[v]++;if (enqueue_num[v] >= vertex_num)return false;visited[v] = 1;}}}}}return true;
}void Print()
{for (int i = 0; i < vertex_num; i++){if (i != source){int p = i;stack<int> s;cout << "顶点 " << source << " 到顶点 " << p << " 的最短路径是: ";while (source != p)  //路径顺序是逆向的,所以先保存到栈{s.push(p);p = path[p];}cout << source;while (!s.empty())  //依次从栈中取出的才是正序路径{cout << "--" << s.top();s.pop();}cout << "    最短路径长度是:" << dist[i] << endl;}}
}int main()
{cout << "请输入图的顶点数,边数,源点:";cin >> vertex_num >> edge_num >> source;for (int i = 0; i < vertex_num; i++)for (int j = 0; j < vertex_num; j++)matrix[i][j] = INT_MAX;  //初始化matrix数组cout << "请输入" << edge_num << "条边的信息:\n";int u, v, w;for (int i = 0; i < edge_num; i++){cin >> u >> v >> w;matrix[u][v] = w;}if (SPFA())Print();elsecout << "Sorry,it have negative circle!\n";return 0;
}

hihocoder1093 SPFA算法模板相关推荐

  1. 单源最短路 SPFA 算法模板

    简介 在图论中,最短路是十分重要的一部分,在很多问题中都有涉及 而现在所讲的 SPFA 算法是十分优秀的算法,时间复杂度为 O(k∗E)O(k*E) 其中 EE 是图的边数,而 kk 是一个常数,一般 ...

  2. (最短路径算法整理)dijkstra、floyd、bellman-ford、spfa算法模板的整理与介绍

    这一篇博客以一些OJ上的题目为载体.整理一下最短路径算法.会陆续的更新... 一.多源最短路算法--floyd算法 floyd算法主要用于求随意两点间的最短路径.也成最短最短路径问题. 核心代码: / ...

  3. ACM算法--spfa算法--最短路算法

    求单源最短路的SPFA算法的全称是:Shortest Path Faster Algorithm.      SPFA算法是西南交通大学段凡丁于1994年发表的.     从名字我们就可以看出,这种算 ...

  4. 图论最短路:Bellman-Ford与其优化SPFA算法的一点理解

    文章目录 前言 一.对Bellman-Ford的深入理解 1. Bellman-Ford有什么用? 2. 什么是松弛操作? 3. Bellman-Ford的k次迭代意义? 4. 一个重要定理 5. 对 ...

  5. ~~spfa 算法(队列优化的Bellman-Ford算法)(附模板题)

    1.SPFA 算法是 Bellman-Ford算法 的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环.SPFA一般情况复杂度是O(m) 最坏情况下复杂度和朴素 Bellman-Fo ...

  6. 图论:SPFA 算法详解( 算法竞赛入门到进阶) HDU 2544 链式前向星 【提供ACM模板+图解,不会都难!】

    文章目录 SPFA简介 链式前向星介绍 SPFA算法思路详细 模板-链式前向星 参考书籍:算法竞赛入门到进阶 罗勇军 SPFA简介 用队列处理Bellman-Ford算法可以很好地优化,这种方法叫做S ...

  7. 详解最短路算法模板(dijkstra+floyd+spfa)

    1.Floyd_Warshall算法 核心思路:d[i][j] = min{d[i][j], d[i][k] + d[k][j]} 从i到j有两种路径,经过k点或是不经过k点,所以我们枚举k即可求所有 ...

  8. 60个必备NOIP模板 python算法模板

    ​ |1快速读入(包括符号) long long read(){long long x=0,f=1;char c=getchar();while((c<'0'||c>'9')&&a ...

  9. ACM算法模板总结(分类详细版)

    本文模均引用于y总的算法模板,网址:AcWing (转载请注明出处,本文属于持续更新ing.......biubiubiu......) 本人码风比起y总真的差远了,所以敲一遍后,还是想把y总的搬上来 ...

最新文章

  1. bootstrap 新闻列表_kuapingUI 2.2 版本发布,跨屏 UI-bootstrap 大组件 UI 框架
  2. 上海巴斯德所在新型冠状病毒早期进化机制方面取得进展
  3. 正确配置Linux系统ulimit值的方法
  4. Java学习笔记(十一)--类与对象
  5. Python中self的用法
  6. c++初学者使用文件流需要了解的一些坑(持续更新)
  7. 【UVA2230】过河
  8. html中从下往上遮罩效果,css制作从下往上逐渐显示的div
  9. 判断程序是否已经运行
  10. python判断英文字母_python判断字符串中是否含有英文 | 个人学习笔记记录
  11. c语言合法常量e8,c语言合法常量定义
  12. Word怎么转换成PDF?
  13. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_5-8.用户模块开发之保存微信用户信息...
  14. JDK 7(Java SE Development Kit)全平台全版本安装包免费下载
  15. mysql 主键和候选键_2.2.2 候选键与主键
  16. 红米(RedmiBook)笔记本无线网卡QCA6174在Linux下wifi异常解决方法
  17. Unity PBR材质
  18. telnet出现端口23连接失败解决办法
  19. 苹果笔记本硬盘替换方案
  20. 室内物流机器人现存痛点分析

热门文章

  1. 线程导入大数据入库_多线程批量插入数据小结
  2. 模拟技术可以预测喷气发动机用合金材料在制造前的微观结构
  3. Racy Puppy Linux 发布
  4. 关于 NoteExpress 和 Endnote 文献管理软件使用的比较
  5. 面对开发平台、数据、工具链和需求等信息不对称,AI 开发者如何进行破局?...
  6. Error 1 error PRJ0019: A tool returned an error code from Moc'ing xxxx.h...
  7. php 添加mp4视频播放器,使用php输出mp4视频
  8. wdr5620千兆版虚拟服务器,TPLINK WDR5620千兆版与斐讯K2P对比评测
  9. HCIP (十四)MPLS 静态LSP
  10. STM32 学习——GPIO