hihocoder1093 SPFA算法模板
来源:互联网 发布:森系服装品牌 知乎 编辑:程序博客网 时间:2024/06/01 09:55
一:背景
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算法
- 样例输入
5 10 3 51 2 9972 3 5053 4 1184 5 543 5 4803 4 7965 2 7942 5 1465 4 6042 5 63
- 样例输出
172
描述
万圣节的晚上,小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为了走出鬼屋至少要走的路程。
#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(); else cout << "Sorry,it have negative circle!\n"; return 0;}
- hihocoder1093 SPFA算法模板
- 基础SPFA算法模板
- SPFA算法模板
- SPFA算法模板
- SPFA算法模板
- spfa 算法模板
- SPFA算法模板
- SPFA算法模板
- spfa算法模板
- Spfa算法模板
- SPFA算法模板
- SPFA算法模板
- Spfa算法 (模板源代码)
- Spfa算法 (模板源代码)
- hdu 2544 spfa算法模板
- 最短路【SPFA】算法模板
- 最短路SPFA算法模板
- 单源最短路 SPFA 算法模板
- 异或密码
- <shader>编程中遇到的问题-too many texture interpolators would be used for ForwardBase pass
- Android多进程模式
- (fzu)Problem I Magic(模拟+后缀匹配)
- Kotlin for Android(七)Kotlin数据类和Gson
- hihocoder1093 SPFA算法模板
- 南师附中集训总结Day4
- Linux下各种错误处理
- 自学PyQuery扎记
- 继承笔记
- 配置Mac的vim,使代码高亮
- Java:模运算
- 匿名内部类笔记
- 如何终止java线程