SPFA算法

一.算法简介

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

很多时候,给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了。SPFA的复杂度大约是O(kE),k是每个点的平均进队次数(一般的,k是一个常数,在稀疏图中小于2)。

但是,SPFA算法稳定性较差,在稠密图中SPFA算法时间复杂度会退化。

实现方法:建立一个队列,初始时队列里只有起始点,在建立一个表格记录起始点到所有点的最短路径(该表格的初始值要赋为极大值,该点到他本身的路径赋为0)。然后执行松弛操作,用队列里有的点去刷新起始点到所有点的最短路,如果刷新成功且被刷新点不在队列中则把该点加入到队列最后。重复执行直到队列为空。

此外,SPFA算法还可以判断图中是否有负权环,即一个点入队次数超过N。

二.算法图解

给定一个有向图,求A~E的最短路。

源点A首先入队,并且AB松弛

扩展与A相连的边,B,C 入队并松弛。

B,C分别开始扩展,D入队并松弛

D出队,E入队并松弛。

E出队,此时队列为空,源点到所有点的最短路已被找到,A->E的最短路即为8

以上就是SPFA算法的过程。

三.算法模板

 #include "bits/stdc++.h"

 using namespace std;
const int maxN = ;
struct Edge
{
int to , next , w ;
} e[ maxN ]; int n,m,cnt,p[ maxN ],Dis[ maxN ];
int In[maxN ];
bool visited[ maxN ]; void Add_Edge ( const int x , const int y , const int z )
{
e[ ++cnt ] . to = y ;
e[ cnt ] . next = p[ x ];
e[ cnt ] . w = z ;
p[ x ] = cnt ;
return ;
} bool Spfa(const int S)
{
int i,t,temp;
queue<int> Q;
memset ( visited , 0 , sizeof ( visited ) ) ;
memset ( Dis , 0x3f , sizeof ( Dis ) ) ;
memset ( In , 0 , sizeof ( In ) ) ; Q.push ( S ) ;
visited [ S ] = true ;
Dis [ S ] = 0 ; while( !Q.empty ( ) )
{
t = Q.front ( ) ;Q.pop ( ) ;visited [ t ] = false ;
for( i=p[t] ; i ; i = e[ i ].next )
{
temp = e[ i ].to ;
if( Dis[ temp ] > Dis[ t ] + e[ i ].w )
{
Dis[ temp ] =Dis[ t ] + e[ i ].w ;
if( !visited[ temp ] )
{
Q.push(temp);
visited[temp]=true;
if(++In[temp]>n)return false;
}
}
}
}
return true;
} int main ( )
{
int S , T ; scanf ( "%d%d%d%d" , &n , &m , &S , &T ) ;
for(int i= ; i<=m ; ++i )
{
int x , y , _ ;
scanf ( "%d%d%d" , &x , &y , &_ ) ;
Add_Edge ( x , y , _ ) ;
} if ( !Spfa ( S ) ) printf ( "FAIL!\n" ) ;
else printf ( "%d\n" , Dis[ T ] ) ; return ;
}

(完)

SPFA算法的更多相关文章

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

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

  2. [知识点]SPFA算法

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

  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. zTree控件的使用

    最常用的使用方式是json格式 .net递归实现对象生成json格式字符串 代码: using System; using System.Collections.Generic; using Syst ...

  2. MVC中Action 过滤

    总结Action过滤器实用功能,常用的分为以下两个方面: 1.Action过滤器主要功能就是针对客服端请求过来的对象行为进行过滤,类似于门卫或者保安的职能,通过Action过滤能够避免一些非必要的深层 ...

  3. 排序练习【sdut 1582】【堆排序】

    排序 Time Limit: 1000ms   Memory limit: 32678K  有疑问?点这里^_^ 题目描述 给你N(N<=100)个数,请你按照从小到大的顺序输出. 输入 输入数 ...

  4. HDU4008 Parent and son(树形DP LCA)

    先记录以1为根时每个节点子树儿子节点的最大与次小值,询问x, y时,先判断x在不在y的子树范围内,若不在,结果为y的儿子结点,后继的最小值. 若x在y的子树范围内,若y儿子最小值是x的前驱,从次小值与 ...

  5. 关于WCF的一些注意事项

    1.服务代理,建立通道的方法,要注意及时关掉代理,因为服务设置有一个服务的最大连接数,超过这个连接数,则后面的连接将会等待,一直到超时,报错!! 2.在已有配置的基础上,利用代码更改终结点,如果重设了 ...

  6. 时间:UTC时间、GMT时间、本地时间、Unix时间戳

    转自:http://blog.csdn.net/u012102306/article/details/51538574 1.UTC时间 与 GMT时间 我们可以认为格林威治时间就是时间协调时间(GMT ...

  7. PMP 第十章 项目沟通管理

    1识别干系人 2规划沟通 3发布信息 4管理干系人期望 5报告绩效 1.沟通的维度有哪些?沟通技巧有哪些? 2.规划沟通管理的目的是什么?沟通渠道的计算(重点).影响沟通技术的因素有哪些?沟通模型的步 ...

  8. MongoDB3.0新特性

    3月3日,MongoDB3.0终于发布了. 主要特点包括了对之前收购的WiredTiger存储引擎的支持,插件式存储引擎API,SCRAM-SHA-1认证机制,并改进了解释功能.此外,包含了自动化.备 ...

  9. 运行在linux上的mysql常用命令

    mysql的注释:--或者# 1.mysql服务进程的命令 service mysqld start;#启动mysql服务 service mysqld status;#查看服务状态 service ...

  10. js整理2

    字符串 类型 var a = "abc"; var b = new String( a ); var c = Object( a ); typeof a; // "str ...