// 此博文为迁移而来,写于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. 与你相遇好幸运,mbview的mbtiles文件分析

    mbview是一个查看.mbtiles文件的本地程序. https://github.com/mapbox/mbview .mbtiles文件就是一个Sqlite文件,用Navicat Premium ...

  2. Hybrid App是如何实现网页语言与程序语言的混合?谁占主体?

    [编者按]本文作者@徐珂铭,一位看好Html5的移动互联网的从业人士.喜爱玩技术,会点JAVA.HTML及CSS,有自己的想法及姑且能表达想法的文字,因此有了自己的文章. 基于HTML5的Web Ap ...

  3. 几年前做家教写的C教程(之二)

    C语言学习宝典(2) 认识C语言中的运算符: (1)算术运算符   (+  -  *  /  %) (2)关系运算符    (>  <  ==  >=  <=  != ) (3 ...

  4. 記錄一次CRS-0184: Cannot communicate with the CRS daemon的解決

    1. 描述: 使用crs_stat –t 命令查看rac服務,直接報CRS-0184: Cannot communicate with the CRS daemon.錯誤 但是奇怪的是我們的DB是沒有 ...

  5. 数据结构之图 Part2 - 1

    邻接矩阵 网上很少有C# 写图的数据结构的例子,实际的项目中也从来没用过Array 这坨东西,随手写个,勿喷. namespace LH.GraphConsole { public struct Gr ...

  6. android 入门-git之上传本地代码到github

    github部分: 1.首先去github网站 上注册一个用户 2.说明 https://guides.github.com/activities/hello-world/ 2.点击 New repo ...

  7. 第三篇:用SOUI能做什么?

    SOUI-DEMO界面预览 在回答SOUI能做什么之前,先看看SVN中demo工程的界面截图: 使用SOUI实现上面的界面主要的工作全在配置几个XML文件,基本不需要写C++代码.(如何配置XML布局 ...

  8. 类模板Queue的实现

    #include <iostream> #include <vector> using namespace std; template <class Type> c ...

  9. (转载)Bash 中的特殊字符大全

    转自:https://linux.cn/article-5657-1.html Linux下无论如何都是要用到shell命令的,在Shell的实际使用中,有编程经验的很容易上手,但稍微有难度的是she ...

  10. kylin cube测试时,报错:org.apache.hadoop.security.AccessControlException: Permission denied: user=root, access=WRITE, inode="/user":hdfs:supergroup:drwxr-xr-x

    异常: org.apache.hadoop.security.AccessControlException: Permission denied: user=root, access=WRITE, i ...