SPFA算法——最短路径
粗略讲讲SPFA算法的原理,SPFA算法是1994年西南交通大学段凡丁提出
是一种求单源最短路的算法
算法中需要用到的主要变量
int n; //表示n个点,从1到n标号
int s,t; //s为源点,t为终点
int d[N]; //d[i]表示源点s到点i的最短路
int p[N]; //记录路径(或者说记录前驱)
queue <int> q; //一个队列,用STL实现,当然可有手打队列,无所谓
bool vis[N]; //vis[i]=1表示点i在队列中 vis[i]=0表示不在队列中
几乎所有的最短路算法其步骤都可以分为两步
1.初始化
2.松弛操作
初始化: d数组全部赋值为INF(无穷大);p数组全部赋值为s(即源点),或者赋值为-1,表示还没有知道前驱
然后d[s]=0; 表示源点不用求最短路径,或者说最短路就是0。将源点入队;
(另外记住在整个算法中有顶点入队了要记得标记vis数组,有顶点出队了记得消除那个标记)
队列+松弛操作
读取队头顶点u,并将队头顶点u出队(记得消除标记);将与点u相连的所有点v进行松弛操作,如果能更新估计值(即令d[v]变小),那么就更新,另外,如果点v没有在队列中,那么要将点v入队(记得标记),如果已经在队列中了,那么就不用入队
以此循环,直到队空为止就完成了单源最短路的求解
SPFA可以处理负权边
定理: 只要最短路径存在,上述SPFA算法必定能求出最小值。
证明:
每次将点放入队尾,都是经过松弛操作达到的。换言之,每次的优化将会有某个点v的最短路径估计值d[v]变小。所以算法的执行会使d越来越小。由于我们假定图中不存在负权回路,所以每个结点都有最短路径值。因此,算法不会无限执行下去,随着d值的逐渐变小,直到到达最短路径值时,算法结束,这时的最短路径估计值就是对应结点的最短路径值。(证毕)
期望的时间复杂度O(ke), 其中k为所有顶点进队的平均次数,可以证明k一般小于等于2。
判断有无负环:
如果某个点进入队列的次数超过N次则存在负环(SPFA无法处理带负环的图)
SPFA的两种写法,bfs和dfs,bfs判别负环不稳定,相当于限深度搜索,但是设置得好的话还是没问题的,dfs的话判断负环很快
int spfa_bfs(int s)
{
queue <int> q;
memset(d,0x3f,sizeof(d));
d[s]=;
memset(c,,sizeof(c));
memset(vis,,sizeof(vis)); q.push(s); vis[s]=; c[s]=;
//顶点入队vis要做标记,另外要统计顶点的入队次数
int OK=;
while(!q.empty())
{
int x;
x=q.front(); q.pop(); vis[x]=;
//队头元素出队,并且消除标记
for(int k=f[x]; k!=; k=nnext[k]) //遍历顶点x的邻接表
{
int y=v[k];
if( d[x]+w[k] < d[y])
{
d[y]=d[x]+w[k]; //松弛
if(!vis[y]) //顶点y不在队内
{
vis[y]=; //标记
c[y]++; //统计次数
q.push(y); //入队
if(c[y]>NN) //超过入队次数上限,说明有负环
return OK=;
}
}
}
} return OK; }
int spfa_dfs(int u)
{
vis[u]=;
for(int k=f[u]; k!=; k=e[k].next)
{
int v=e[k].v,w=e[k].w;
if( d[u]+w < d[v] )
{
d[v]=d[u]+w;
if(!vis[v])
{
if(spfa_dfs(v))
return ;
}
else
return ;
}
}
vis[u]=;
return ;
}
SPFA算法——最短路径的更多相关文章
- 最短路径问题的Dijkstra和SPFA算法总结
Dijkstra算法: 解决带非负权重图的单元最短路径问题.时间复杂度为O(V*V+E) 算法精髓:维持一组节点集合S,从源节点到该集合中的点的最短路径已被找到,算法重复从剩余的节点集V-S中选择最短 ...
- 最短路径--SPFA 算法
适用范围:给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了. 我们约定有向加权图G不存在负权回路,即最短路径一 ...
- Bellman-Ford & SPFA 算法——求解单源点最短路径问题
Bellman-Ford算法与另一个非常著名的Dijkstra算法一样,用于求解单源点最短路径问题.Bellman-ford算法除了可求解边权均非负的问题外,还可以解决存在负权边的问题(意义是什么,好 ...
- 最短路径算法之四——SPFA算法
SPAF算法 求单源最短路的SPFA算法的全称是:Shortest Path Faster Algorithm,该算法是西南交通大学段凡丁于1994年发表的. 它可以在O(kE)的时间复杂度内求出源点 ...
- 最短路径——SPFA算法
一.前提引入 我们学过了Bellman-Ford算法,现在又要提出这个SPFA算法,为什么呢? 考虑一个随机图(点和边随机生成),除了已确定最短路的顶点与尚未确定最短路的顶点之间的边,其它的边所做的都 ...
- 数据结构与算法--最短路径之Bellman算法、SPFA算法
数据结构与算法--最短路径之Bellman算法.SPFA算法 除了Floyd算法,另外一个使用广泛且可以处理负权边的是Bellman-Ford算法. Bellman-Ford算法 假设某个图有V个顶点 ...
- 图的最短路径-----------SPFA算法详解(TjuOj2831_Wormholes)
这次整理了一下SPFA算法,首先相比Dijkstra算法,SPFA可以处理带有负权变的图.(个人认为原因是SPFA在进行松弛操作时可以对某一条边重复进行松弛,如果存在负权边,在多次松弛某边时可以更新该 ...
- 图论-最短路径--3、SPFA算法O(kE)
SPFA算法O(kE) 主要思想是: 初始时将起点加入队列.每次从队列中取出一个元素,并对所有与它相邻的点进行修改,若某个相邻的点修改成功,则将其入队.直到队列为空时算法结束. 这个算 ...
- 最短路径:我的理解--SPFA算法
SPFA算法 求单源最短路的SPFA算法的全称是:Shortest Path Faster Algorithm. 最短路径快速算法-SPFA算法是西南交通大学段凡丁于1994年发表的. 适用范围:给定 ...
随机推荐
- 九度OJ 1048:判断三角形类型 (基础题)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:6794 解决:3361 题目描述: 给定三角形的三条边,a,b,c.判断该三角形类型. 输入: 测试数据有多组,每组输入三角形的三条边. 输 ...
- 如果这种方式导致程序明显变慢或者引起其他问题,我们要重新思考来通过 goroutines 和 channels 来解决问题
https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/09.3.md 9.3 锁和 sync 包 在一些复杂的程序中,通常通 ...
- php计算数组的维数
function array_dim($arr){ if(!is_array($arr)) return 0; else{ $max1 = 0; foreach($arr as $item1){ $t ...
- Git you are not allowed to push code to protected branches on this project?
error: You are not allowed to push code to protected branches on this project....error: failed to pu ...
- Coin和Token有什么区别
在币圈,经常可以听到“coin”和“token”这些词汇,他们究竟分别代表什么,有什么区别呢?下面本文就和大家一起来扒一扒. 什么是coin? coin (包括山寨coin)是一种数字货币,它通过加密 ...
- ABAP div / mod的用法
1.divdiv是用于取两数相除的商的,c = a div b,得到的c的值就是a除b的商.2.// 是用于取两数相除的结果的.c = a / b,如果c是i数据类型的,这个语法会进行四舍五入的.3. ...
- angularJs 购物车模型
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel= ...
- JDBC通用方法实现
在一些测试项目中会用到纯粹的jdbc操作数据库,下面提供统一的方法实现. import java.sql.CallableStatement; import java.sql.Connection; ...
- :style动态设置属性
前段时间做页面时需要动态设置背景图片,每一种框架都会遇见类似的需求,特记录下来,以免不时之需: <!DOCTYPE html> <html> <head> < ...
- error:Flash Download failed-“Cortex-M3”,“Programming Algorithm”【转】
本文转载自:http://www.yfrobot.com/thread-11763-1-1.html 最近安装了KEIL5,在使用KEIL5和JLIN实现在线调试功能时,一定会在Utilities选项 ...