// 此博文为迁移而来,写于2015年4月9日,不代表本人现在的观点与看法。原始地址:http://blog.sina.com.cn/s/blog_6022c4720102vx93.html

1、前言
       最短路算法有很多种,类似于Floyd和Dijkstra都是很早之前就学了的。其实每种最短路算法有各自的优势。Floyd适合于跑完全图,但是效率太慢(O(n3))。Dijkstra适合于跑没有负权的图,效率为O(n2)。而今天介绍的SPFA算法,是有一位中国人——段凡丁所提出来的(其实我很想吐个槽。。为什么人家弗洛伊德大叔提出了算法就叫弗洛伊德算法,迪杰斯特拉大爷提出的东西就叫迪杰斯特拉算法,段凡丁提出来的算法就变成了什么鬼SPFA(Shortest Path Faster Algorithm)。。严重的歧视啊。。。)
       其实SPFA没什么要讲的。看了一下模板就瞬间懂了。
       
2、概念
       SPFA算法,是队列实现的Bellman-Ford算法。非常好理解,都知道BFS跑无权迷宫吧?其实SPFA可以直接理解为BFS跑有权图。因为它的形式和BFS太像了。大致流程是用一个队列来进行维护。 初始时将源加入队列。 每次从队列中取出一个元素,并对所有与他相邻的点进行松弛(松弛的意思自行脑补吧,看了程序就懂了),若某个相邻的点松弛成功,则将其入队。 直到队列为空时算法结束。先上代码:
 
//代码更新于20160916
#include <cstdio>
#include <cstring> #define MAXN 10000
#define MAXM 100000
#define INF 0x3f3f3f3f int T, n, m, u, v, w;
int h[MAXN], q[MAXN], o, dis[MAXN], vis[MAXN], s, t; struct Edge {
int v, next, w;
} edge[MAXM * ]; void addEdge(int u, int v, int w) {
edge[++o] = (Edge) {v, h[u], w}, h[u] = o;
} int SPFA(int s, int t) {
int head = , tail = ;
while (head != tail) {
int o = q[head];
for (int x = h[o]; x; x = edge[x].next) {
int v = edge[x].v;
if (dis[o] + edge[x].w < dis[v]) {
dis[v] = dis[o] + edge[x].w;
if (!vis[v]) q[tail++] = v, vis[v] = ;
}
}
vis[o] = ;
head++;
}
return dis[t];
} int main() {
scanf("%d %d", &n, &m);
for (int i = ; i <= m; i++) {
scanf("%d %d %d", &u, &v, &w);
addEdge(u, v, w), addEdge(v, u, w);
}
scanf("%d", &T);
for (int i = ; i <= T; i++) {
memset(vis, , sizeof(vis)), memset(dis, INF, sizeof(dis));
scanf("%d %d", &s, &t);
dis[s] = , vis[s] = , q[] = s;
printf("%d", SPFA(s, t));
}
return ;
}
       初始化:设dis[i]代表目前源点到i点的最短距离,开始时dist全部为INF(无穷大),只有dis[s]=0。
       SPFA:维护一个队列,里面存放所有需要进行迭代的点。初始时队列中只有一个点s。用一个vis[i]记录i点是否处在队列中。每次迭代,取出队头的点v,依次枚举从v出发的边v->u,设边的长度为len,判断dis[v]+len是否小于dis[u],若小于则改进dis[u],并且由于s到u的最短距离变小了,有可能u可以改进其它的点,所以若u不在队列中,就将它放入队尾。这样一直迭代下去直到队列变空,也就是s到所有点的最短距离都确定下来,结束算法。
       备注:SPFA还有一个很强大的功能,可以判负权环。若一个点入队次数超过n,则有负权环。

[知识点]SPFA算法的更多相关文章

  1. 最短路径问题的Dijkstra和SPFA算法总结

    Dijkstra算法: 解决带非负权重图的单元最短路径问题.时间复杂度为O(V*V+E) 算法精髓:维持一组节点集合S,从源节点到该集合中的点的最短路径已被找到,算法重复从剩余的节点集V-S中选择最短 ...

  2. SPFA算法

    SPFA算法 一.算法简介 SPFA(Shortest Path Faster Algorithm)算法是求单源最短路径的一种算法,它是Bellman-ford的队列优化,它是一种十分高效的最短路算法 ...

  3. SPFA算法学习笔记

    一.理论准备 为了学习网络流,先水一道spfa. SPFA算法是1994年西南交通大学段凡丁提出,只要最短路径存在,SPFA算法必定能求出最小值,SPFA对Bellman-Ford算法优化的关键之处在 ...

  4. 用scheme语言实现SPFA算法(单源最短路)

    最近自己陷入了很长时间的学习和思考之中,突然发现好久没有更新博文了,于是便想更新一篇. 这篇文章是我之前程序设计语言课作业中一段代码,用scheme语言实现单源最段路算法.当时的我,花了一整天时间,学 ...

  5. SPFA算法心得

    SPFA算法是改进后的Bellman-Ford算法,只是速度更快,而且作为一个算法,它更容易理解和编写,甚至比Dijkstra和B-F更易读(当然,Floyd是另一回事了,再也没有比Floyd还好写的 ...

  6. 最短路径--SPFA 算法

    适用范围:给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了. 我们约定有向加权图G不存在负权回路,即最短路径一 ...

  7. Bellman-Ford & SPFA 算法——求解单源点最短路径问题

    Bellman-Ford算法与另一个非常著名的Dijkstra算法一样,用于求解单源点最短路径问题.Bellman-ford算法除了可求解边权均非负的问题外,还可以解决存在负权边的问题(意义是什么,好 ...

  8. UVA 10000 Longest Paths (SPFA算法,模板题)

    题意:给出源点和边,边权为1,让你求从源点出发的最长路径,求出路径长度和最后地点,若有多组,输出具有最小编号的最后地点. #include <iostream> #include < ...

  9. 最短路径算法之四——SPFA算法

    SPAF算法 求单源最短路的SPFA算法的全称是:Shortest Path Faster Algorithm,该算法是西南交通大学段凡丁于1994年发表的. 它可以在O(kE)的时间复杂度内求出源点 ...

随机推荐

  1. Tomcat7配置数据源

    http://www.cnblogs.com/ITtangtang/archive/2012/05/21/2511749.html

  2. ASP.NET MVC中Controller返回值类型ActionResult

    1.返回ViewResult视图结果,将视图呈现给网页 public class TestController : Controller { //必须存在Controller\Test\Index.c ...

  3. jQuery插件:跨浏览器复制jQuery-zclip(转载)

    转载地址:http://www.cnblogs.com/linjiqin/p/3532451.html jQuery-zclip是一个复制内容到剪贴板的jQuery插件,使用它我们不用考虑不同浏览器和 ...

  4. RecyclerView导入依赖包

    1. eclipse 上的导入: 如下进入Android SDK的如下路径, \android-sdk\extras\android\m2repository\com\android\support\ ...

  5. 关于Mesos和Kubernetes的区别

    这个主题应该和服务发现注册一样,进入视野...

  6. poj 1008:Maya Calendar(模拟题,玛雅日历转换)

    Maya Calendar Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 64795   Accepted: 19978 D ...

  7. Power BI for Office 365介绍

    微软在七月份发布了一个新产品,它建立在微软的云的第一个数据平台- Power BI for Office 365.Satya Nadella,服务器和工具业务总裁,在当天的上午在微软的年度全球合作伙伴 ...

  8. 【leetcode】Reverse Integer

    题目描述: Reverse digits of an integer. Example1: x = 123, return 321Example2: x = -123, return -321 很简单 ...

  9. 跟着鸟哥学Linux系列笔记0-扫盲之概念

    相关缩写全称: POSIX(Portable Operation System Interface):可携式操作系统接口,重点在于规范内核与应用之间的接口,由IEEE定义发布 IEEE: 美国电气与电 ...

  10. BZOJ 3289: Mato的文件管理 莫队+BIT

    3289: Mato的文件管理 Description Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号.为了防止他人偷拷,这些资料都是加密过的 ...