SPFA算法总结
来源:互联网 发布:微信视频强制分享源码 编辑:程序博客网 时间:2024/05/29 14:27
SPFA算法
一、spfa算法
很多时候,给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了。
思想:用于求单源最短路径,可以适用于负边权的情况。spfa(Shortest Path Faster Algorithm)算法是bellman-ford算法的队列优化。设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且 v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。
二、模板
#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;const int N = 105;const int INF = 0x3f3f3f3f;int map[N][N], dist[N];bool visit[N];int n, m;void init() //初始化{ int i, j; for (i = 1; i < N; i++) { for (j = 1; j < N; j++) { if (i == j) { map[i][j] = 0; } else { map[i][j] = map[j][i] = INF; } } }}/** * SPFA算法. * 使用spfa算法来求单元最短路径 * 参数说明: * start:起点 */void spfa(int start){ queue<int> Q; int i, now; memset(visit, false, sizeof(visit)); for (i = 1; i <= n; i++) { dist[i] = INF; } dist[start] = 0; Q.push(start); visit[start] = true; while (!Q.empty()) { now = Q.front(); Q.pop(); visit[now] = false; for (i = 1; i <= n; i++) { if (dist[i] > dist[now] + map[now][i]) { dist[i] = dist[now] + map[now][i]; if (visit[i] == 0) { Q.push(i); visit[i] = true; } } } }}int main(){ while(scanf("%d%d",&n,&m)!=EOF) { init(); while(m--) { int a,b,c; scanf("%d%d%d",&a,&b,&c); if(map[a][b] > c) { map[a][b] = map[b][a] = c; } } spfa(1); printf("%d\n",dist[n]); } return 0;}
//效率最高#include <cstdio> #include <iostream>#include <cstring>#define Maxn 100#define Maxm 10000#define Max 10000int used[Maxn],outqueue[Maxn],head[Maxn],queue[Maxn],low[Maxn],n,m;struct Edge{ int to,w,next;} edge[Maxm];bool SPFA(int start){ int i =0, iq = 0; used[start] = 1; queue[iq++] = start; low[start] = 0; while (i != iq) { int top = queue[i]; used[top] = 0; outqueue[top]++;//用来判断是否有环路 if (outqueue[top] > n) return false; for (int k = head[top]; k != -1; k = edge[k].next)//宽搜每条边 { if (low[edge[k].to] > low[top] + edge[k].w)//对点进行松驰 low[edge[k].to] = low[top] + edge[k].w; if (!used[edge[k].to]) { used[edge[k].to] = 1; queue[iq++] = edge[k].to; } } i++; } return true;}int main(){ while (scanf ("%d%d", &n,&m) != EOF) { memset (used, 0,sizeof(used)); memset (head, -1,sizeof(head)); memset (outqueue, 0,sizeof(outqueue)); memset (low, Max, sizeof(low)); int k = 0; while (m--) { int a,b,w; scanf ("%d%d%d", &a, &b, &w); edge[k].to = b; edge[k].w = w; edge[k].next = head[a]; head[a] = k++; } if (SPFA(1)) printf ("%d\n", low[n]); else printf ("不存在最短\n"); }}
//用stl实现队列#include <cstdio>#include <queue>#include <iostream>#include <cstring>#define Maxn 100#define Maxm 10000#define Max 10000using namespace std;int used[Maxn],outqueue[Maxn],head[Maxn],low[Maxn],n,m;struct Edge{ int to,w,next;} edge[Maxm];bool SPFA (int start){ queue <int> a; used[start] = 1; low[start] = 0; a.push(start); while (!a.empty()) { int top = a.front(); a.pop(); outqueue[top]++; if (outqueue[top] > n) return false; for (int k = head[top]; k!= -1; k = edge[k].next) { if (low[edge[k].to] > low[top] + edge[k].w) low[edge[k].to] = low[top] + edge[k].w; if (!used[edge[k].to]) { used[edge[k].to] = 1; a.push(edge[k].to); } } } return true;}int main(){ while (scanf ("%d%d", &n,&m) != EOF) { memset (used, 0,sizeof(used)); memset (head, -1,sizeof(head)); memset (outqueue, 0,sizeof(outqueue)); memset (low, Max, sizeof(low)); int k = 0; while (m--) { int a,b,w; scanf ("%d%d%d", &a, &b, &w); edge[k].to = b; edge[k].w = w; edge[k].next = head[a]; head[a] = k++; } if (SPFA(1)) printf ("%d\n", low[n]); else printf ("不存在最短\n"); }}
阅读全文
0 0
- SPFA算法总结
- SPFA算法总结[Shortest Path Faster Algorithm]
- SPFA 算法
- SPFA 算法
- SPFA算法
- SPFA算法
- SPFA算法
- SPFA算法
- Spfa算法
- SPFA算法
- SPFA 算法
- Spfa算法
- SPFA算法
- SPFA算法
- SPFA算法
- SPFA算法
- spfa算法
- SPFA算法
- 未来五年最具前景的一门编程语言是什么?
- 你的工资基础决定你的前途
- 《Learning RabbitMQ》阅读笔记(1.简介)
- Linux的SOCKET编程详解
- android 开源数据层框架。解放数据吧
- SPFA算法总结
- 阿里巴巴Java规范开发手册
- Android深度探索:HAL与驱动开发学习笔记--内存管理(学习重点)
- 下一代数据可视化分析系统的七个特征(二)
- 序列化和反序列化二叉树
- MediaPlayer实现金额的语音播报功能
- linux上printf出带颜色字体
- 洋河梦之蓝M9政府专供 是真是假?
- C++笔记之抽象类与接口类