spfa初探

java实现SPFA算法 1 问题描述 何为spfa(Shortest Path Faster Algorithm)算法? spfa算法功能:给定一个加权连通图,选取一个顶点,称为起点,求取起点到其它所有顶点之间的最短距离,其显著特点是可以求含负权图的单源最短路径,且效率较高。(PS:引用自百度百科:spfa是求单源最短路径的一种算法,它还有一个重要的功能是判负环(在差分约束系统中会得以体现),在Bellman-ford算... 阅读详情

下面先来看一下spfa是什么

转载自http://www.cnblogs.com/scau20110726/archive/2012/11/18/2776124.html


粗略讲讲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无法处理带负环的图)

 



拿杭电的通畅工程续来练了个手



#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;
int map[220][220];
int vis[220];
int dis[220];
int c[220]; //判断负环 
#define INF 99999999
void spfa(int s,int n)
{
	queue<int> q;
	memset(vis,0,sizeof(vis));
	for(int i=0;i<n;i++) dis[i]=INF;
	memset(c,0,sizeof(c));
	q.push(s);
	vis[s]=1;
	dis[s]=0;
	c[s]=1;
	while(!q.empty())
	{
		int x=q.front();
		q.pop();vis[x]=0;
		for(int i=0;i<n;i++)
		if(i!=x)
		{
			if(dis[i]>dis[x]+map[x][i])
			{
				dis[i]=dis[x]+map[x][i];
			
			if(vis[i]==0)
			{
				vis[i]=1;
				c[i]++;
				q.push(i);
				
			}
		    }
		}
	}
	return ;
}
int main()
{
	int n,m,i,j,k,a,b,x,s,e;
	while(~scanf("%d%d",&n,&m))
	{
	 for(i=0;i<n;i++)
	  for(j=0;j<n;j++)
	   if(i!=j)map[i][j]=INF;
	    else map[i][j]=0;
	 for(i=1;i<=m;i++)
	 {scanf("%d%d%d",&a,&b,&x);
	  if(x<map[a][b])
	  {map[a][b]=x;
	   map[b][a]=x;
	  }
	 }
	 scanf("%d%d",&s,&e);   
	 spfa(s,n);
	 if(dis[e]<INF)printf("%d\n",dis[e]);
	   else printf("-1\n"); 
	}
	return 0;
 } 
(ctr的自我吐槽……不会用前向星,不会用链表……只会用邻接矩阵……省赛要完……)



SPFA算法详解:高效的单源最短路径算法 介绍spfa算法求解最短路和判断负环的思路 阅读详情

相关推荐

为啥说SPFA已死?三种图论算法太难懂?深入浅出谈图论,看这篇文章就够了

为了给参赛者出难题,他们会设计一些“恶意”图结构——例如具有大量负权边或复杂的环形结构,这些图会让 SPFA 的队列膨胀得离谱,从而使算法的最坏时间复杂度从 (O(V + E)) 升至 (O(VE))。Floyd-Warshall 算法和前面两位不同,它是个全局性算法,能够在 (O(V^3)) 的时间复杂度内解决任意两点之间的最短路径问题。这使得它在稠密图(边数远大于节点数)的情况下表现较好,尤其是在没有负权边的场景下,Dijkstra 是稳定且高效的选择。但在算法竞赛中,它的命运往往由出题人掌控。

qq_36916968的博客 3432

SPFA 算法:实现原理及其应用

SPFA算法,全称为Shortest Path Faster Algorithm,是求解单源最短路径问题的一种常用算法,它可以处理有向图或者无向图,边权可以是正数、负数,但是不能有负环。

MissingPastDay的博客 3252

hdu4889 spfa(造数据卡spfa

题目是给了你一个spfa+slf优化的程序,然后,让你造个数据卡掉他, 其实那个slf优化根本不算是优化,只是在某些图上可能会更好,但是可以通过直接构造图将其由原本spfa最坏nm的复杂度卡成2^n复杂度 至于具体的,这题是曹圣 (http://blog.youkuaiyun.com/jinzhao1994) 给我讲的,他那里写的很详细,我就直接copy了

Durandal的专栏 3849

搜索与图论 - spfa 算法

spfa 算法

每天进步一点点! 6257

spfa算法_C++详解

SPFA算法的全称是:Shortest Path Faster Algorithm,该算法是西南交通大学段凡丁于1994年发表的,它可以在O(kE)的时间复杂度内求出源点到其他所有点的最短路径,其中k为所有顶点进队的平均次数,可以证明k一般小于等于2,可以处理负边,但无法处理带负环的图(负环和负边不是一个概念)。

m0_54615144的博客 1350

Python新手必看:5分钟搞定睿尔曼机械臂基础控制(附代码示例)

本文为Python新手提供了快速上手睿尔曼机械臂基础控制的实战指南。通过详细的步骤讲解和代码示例,介绍了从环境搭建、网络配置、SDK安装到建立连接、执行关节运动(movej)、直线运动(movel)等核心控制指令的全过程,帮助零基础开发者快速实现机械臂的基础操控。

hp777的博客 328

POJ-1511 初探Bellman-Ford,再水SPFA模板题..

昨天狐狸大大交流~~会了bellman-ford..    bellman-ford简单概括就是:      /*             d [ i ]  来记录源点到 i 点的最小距离,初始值源点的 d [ ] 为0,其他的点为一个足够大的数            l

zzyzzy12 2360

ARKit面部动画实战:如何用blend shape让数字人表情更自然(附中文对照表)

本文深入探讨了如何利用ARKit的blend shape技术驱动数字人面部动画,以实现更自然生动的表情。文章提供了详细的blend shape中文对照表,并分享了实战技巧,包括构建复合表情动画序列、处理不对称性与微表情,以及性能优化策略,旨在帮助开发者高效提升数字人的表情表现力。

weixin_29292535的博客 324

SPFA算法

一.算法简介 SPFA(Shortest Path Faster Algorithm)算法是求单源最短路径的一种算法,它是Bellman-ford的队列优化,它是一种十分高效的最短路算法。 很多时候,给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了。SPFA的复杂度大约是O(kE),k是每个点的平均进队次数(...

孙荣达的博客 2万+

AAAI 2025杰出论文解读:神经符号推理与生物多样性计算的突破性进展

本文深度解读了AAAI 2025两篇杰出论文的突破性进展。南京大学周志华团队提出“溯因反射”框架,高效解决神经符号推理中的“不一致性”核心难题,为构建可靠、可解释的AI系统提供了新路径。斯坦福大学等机构的DiVShift研究,则系统分析了公民科学数据中的复杂分布偏移,为利用海量数据精准监测生物多样性及应对AI数据偏差提供了关键方法论。

weixin_29085865的博客 501

微带功分器设计与ADS-EM联合仿真实战解析

本文详细解析了微带功分器设计与ADS-EM联合仿真的实战技巧,涵盖特性阻抗计算、ADS原理图设计、版图生成与EM仿真等关键步骤。通过实际案例分享,帮助工程师掌握射频电路设计中的核心技术和调试方法,提升功分器设计效率与性能。

weixin_29280219的博客 449

spfa

文章目录前言一、什么是spfa算法二、例题,代码1.AcWing 851. spfa求最短路本题分析AC代码2.AcWing 852. spfa判断负环本题分析AC代码三、时间复杂度 前言 复习acwing算法基础课的内容,本篇为讲解基础算法:spfa,关于时间复杂度:目前博主不太会计算,先鸽了,日后一定补上。 一、什么是spfa算法 计算最短路算法的一种,spfa算法可以说是bellman-ford算法的算法优化版本,相较于Dijkstra算法,它可以计算有负权边的最短路,下图来自ACWing算法基.

佛系更新 1530

芒果YOLO11改进172:ARConv自适应旋转卷积,全网首发 | 即插即用:以增强其表征能力,从而准确检测方向物体,ICCV顶会论文idea

ARConv自适应旋转卷积,全网首发 | 即插即用:以增强其表征能力,从而准确检测方向物体,ICCV顶会论文idea

包括YOLOv5、YOLOv7、YOLOv8等模型改进 1515

spfa算法

spfa算法简介 spfa算法是shortest path fastest algorithm的缩写。再通常情况下,是一种比较高效的求解最短路的算法。spfa的本质是广度优先搜索,将图所有的边都遍历一遍。时间复杂度是O(m),其中m是图的边数。 spfa算法的用途 spfa算法用来解决单源最短路问题,可以求解从某个点开始,到图中其他所有点的最短距离。 spfa算法的实现步骤 实现spfa算法需要一个队列q,一个标记数组vis[N]用来标记某点是否已经被搜索过。数组dist[N],用来存储起点到..

qq_41729237的博客 1万+

智能手环嵌入式系统:STM32+ESP8266多传感器健康监护设计

可穿戴健康监测设备是物联网与边缘计算融合的典型应用,其核心在于多源生理信号采集、低功耗实时处理及安全云协同。基于光电容积脉搏波(PPG)的心率与血氧检测、NTC热敏电阻体温测量、加速度-角速度融合跌倒判据等技术,构成了老年健康监护的基础感知能力;而STM32主控与ESP8266协处理器分工架构,则实现了计算资源与通信负载的高效解耦。该方案依托FreeRTOS多任务调度、阿里云IoT物模型标准化交互及MQTT双向通信,兼顾实时性、可靠性和工程可维护性,广泛适用于居家养老、慢病管理与远程健康预警等场景。

weixin_33256096的博客 97

【VxWorks】Vxworks、QNX、Xenomai、Intime、Sylixos、Ucos等实时操作系统的性能特点

VxWorks 操作系统是美国WindRiver公司于1983年设计开发的一种嵌入式实时操作系统,是嵌入式开发环境的关键组成部分。其内核支持多任务调度(采用基于优先级抢占方式,同时支持同优先级任务间的分时间片调度)、任务间的同步、进程间通信机制、中断处理、定时器和内存管理机制等,且提供了一个快速灵活的与 ANSIC 兼容的 I/O 系统,网络支持 对其它VxWorks系统和TCP/IP网络系统的"透明"访问。具有良好的持续发展能力、良好的可靠性、卓越的实时性和高性能的内核以及友好的用户开发环境。

smartvxworks的博客 1064

【图论】SPFA

讲解SPFA

OI博客 1843

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

如何卡SPFA

由于一个校内最短路题数据太水,于是就和司机一起研究如何卡SPFA... 卡SPFA的基本思路是弄一个网格图,然后这个网格图行比列小得多,比如10*10000之类的... 然后对于竖着的边边权就设多么小,然后横着的边权就设多么大(比如1和rand()%10000+10) 还可以在图里随机加一些奇怪的边. 然后对于点个数1e5,边个数2e5的有向图,随机或随机+SLF的SPFA就被卡到了入队1

yfzcsc的博客 1万+

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

SPFA判负环

SPFA和Dijkstra都是解决最短路问题的算法,都有各自的特点: SPFA: 1.可以判断是否存在负环 2.按层级松弛 3.有些数据可以卡掉SPFA Dijkstra: 1.效率稳定 2.不可以解决负边、负环的图 一般处理无负边的最短路问题时,使用Dijkstra。在判断是否存在负环的时候使用SPFA。这里主要讲如何使用SPFA判断正负环。 原理 1.一个n个点的连通图中,经过n-1条边肯定可...

陈颜的博客 6105

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

SPFA回炉重造

迪杰斯特拉求最短路的步骤是每次找最距离源点最近的点进行更新。SPFA求最短路的步骤是用被更新过的点来做下一次更新。当一个点被松弛之后,判断该点是不是已经在队列中,不在的话压入队列。 需要注意的是,虽然说SPFA是Bellman-Ford算法的优化,但是准确的说是假优化,事实上,所有Bellman-Ford算法的优化都会被精心构造的图卡回Bellman-Ford的复杂度。然而,Bellman-Ford及其优化的算法(包括SPFA)可以用来判断负环。(感觉这是唯一的剩余价值了) 最短路例题 POJ2387 SP

陈颜的博客 3021

浅谈Spfa

一、前言 1、什么是spfa 在很多的博客和百科里都有介绍比Dj算法更强大,比ford更省时间,这里就不多说了; 2、为什么他能处理带负权的 在每次碰到更优的解时,将下一个节点再次入队列,会按照路径顺次的优化之前的。而Dj算法后面的最优是建立在当前的,只能做加法,即使有更小的也不能回头了; 3、什么是负环、怎样判断负环? 所谓负环,不是带有负权的回路都是,而是回路的权值和为负数的才叫负环。 判断...

月殇 896

差分约束,BFS-SPFA 与 DFS-SPFA 的优劣

差分约束系统 差分约束系统 是一种特殊的 $n$ 元一次不等式组,它包含 $n$ 个变量 $x_1,x_2,...,x_n$ 以及 $m$ 个约束条件,每个约束条件是由两个其中的变量作差构成的,形如 $x_i-x_j\leq c_k$ ,其中 $c_k$ 是常数(可以是非负数,也可以是负数)。我们要解决的问题是:求一组解 $x_1=a_1,x_2=a_2,...,x_n=a_n$ ,使...

weixin_30699465的博客 871
上一篇: poj 3070 矩阵快速幂求斐波拉契数列
下一篇: hdu 1102 最小生成树prim模板题
ctrss
博客等级 码龄11年 1粉丝 35原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值