浅谈 SPFA 的堆优化

BZOJ 4152 浅谈堆优化的SPFA算法 世界真的很大 其实这道题一看就能想到最短路 关键是怎么建边 看一下数据,200000个点 每个点两两建边的话肯定会超时 好像说多了先看一下题吧: description给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用。 input第一行包含一个正整数n(2<=n<=200000),表示点数。 接下来n行 阅读详情

我下午在做最短路时想到了 SPFA 可以使用堆优化来做,并且经过实践我得出了它确实有效。

之后我上网搜索,网络上很少有过关于 SPFA 堆优化的论述,就算有也讲的不太清楚,因此此文章就来回答一下三个问题,如有错误,欢迎私信。

问:它的运行时间是否在遇到大部分数据时都小于等于普通的 SPFA ?

答:它的运行时间在正权图上等价于 Dijkstra 算法,但在负权图上可以被卡到指数级的复杂度。

问:它和 Dijkstra 一样吗?

答:它和 Dijkstra 不一样。应为它支持一个点重复入堆,而 Dijkstra 遍历到某结点时必须判断该结点有没有被统计过,若被统计过应当直接跳过。

问:它能否继承普通 SPFA 的特点,如判断负环和处理负权图?

答:能。堆优化的 SPFA 能够继承普通 SPFA 处理负权图的能力,并且同样能够检测负权环。这是因为它在松弛过程中保留了 Bellman-Ford 算法的核心特性:对每个顶点进行最多 n−1n-1n−1 次松弛操作(其中 nnn 是顶点数)。如果某个顶点在算法结束时仍然可以被松弛,或者某个顶点被松弛的次数超过了 n−1n-1n−1 次,那么图中就存在负权环。需要注意的是,它在处理某些负权图上可以被卡到指数级的复杂度。

总结

SPFA 的堆优化在正权图上完全可以被 Dijkstra 算法所替代,而在负权图的复杂度也是不如普通的 SPFA 的。在选择最短路径算法时,你仍然需要根据问题的具体要求和图的特性来做出明智的决策。

参考代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,d,h[500005],ans[100005],js;
struct edge{
	int n,v,w;
}a[500005];
struct node{
	int id,w;
	bool operator<(const node &a)const{
		return w>a.w;
	}
};
void add(int u,int v,int w){
	a[++js].n=h[u];
	a[js].v=v;
	a[js].w=w;
	h[u]=js;
}
void spfa(int d){
	priority_queue<node> q;
	memset(ans,0x3f3f3f3f3f,sizeof ans);
	ans[d]=0;
	q.push(node{d,0});
	while(q.empty()==0){
		node f=q.top();
		q.pop();
} 
浅谈路径规划算法之SPFA算法 SPFA算法        求单源最短路的SPFA算法的全称是:Shortest Path Faster Algorithm。SPFA算法是西南交通大学段凡丁于1994年发表的。从名字我们就可以看出,这种算法在效率上一定有过人之处。 很多时候,给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了。有人称sp 阅读详情

相关推荐

C++队列优化的Bellmanford最短路算法(SPFA)

摘要:VC/C++源码,算法相关,队列优化,最短路径算法  C++队列优化的Bellmanford最短路算法(SPFA),使用C++实现的Queue improved Bellman-Ford单源最短路算法,在国内还被叫做SPFA。这个程序输入一个图,找到图中的一个点,这个点到最远点的长度最短。图使用邻接表保存。

堆优化Dijkstra()算法+spfa算法(模板)

题目链接 题意: T组样例 n个顶点,m条单向边 m行 ui,vi,wi. 求源点1到其它点来回最短路 最后输出所有来回最短路相加之和 0<n≤20000,m≤60000,1≤T≤10,0≤ci​≤10^9,1≤ui​,vi,wi​≤n 题解: 单源最短路,且边权值为正数,n数据太大,邻接表存图。 解法1:spfa算法 解法2:堆优化Dijkstra()算法 如何实现堆优化: 不同结构体,用pair容器,pair可以放两个元素,相当于一个结构体,然后优先队列自动从小到大排序,排序先按pair中第一

Helinshan的博客 1525

FPGA数字下变频实战:用Vivado DDS IP核实现IQ采样与频率校正(附MATLAB仿真对比)

本文提供了一份基于Vivado DDS IP核实现FPGA数字下变频(DDC)的完整工程指南。详细阐述了IQ采样的原理、DDC链路构建、DDS频率校正的工程实现,并重点介绍了如何利用MATLAB搭建黄金参考模型进行全链路仿真与对比验证,分享了关键的调试技巧与性能优化建议。

t1u2v的博客 810

最短路(堆优化dijkstra,spfa,bellman-ford)

最短路的相关算法,dijkstra,bellman-ford, spfa

m0_74453078的博客 866

Arduino应用——PWM控制直流电机风扇

Arduino应用——PWM控制直流电机风扇PWM原理实验器件功能描述如何改变文本的样式插入链接与图片实现代码生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 最近在使用arduino UNO开发板完成课程小作业。其中一个要求设计一个电风扇控制系统,要求能够通过PWM调节风扇的转速。期间搜索了许多例程和方法,但受限于器件,效果不

hypecycle的博客 2万+

Silvaco TCAD 2018安装后,如何配置TonyPlot 5.0.22.R并解决绘图报错?

本文详细介绍了在Windows系统上安装Silvaco TCAD 2018后,如何正确配置TonyPlot 5.0.22.R并解决常见的绘图报错问题。内容包括版本兼容性分析、环境变量设置、常见错误解决方案以及性能优化建议,帮助用户顺利完成仿真结果的可视化工作。

weixin_31031711的博客 419

关于SPFA的优化

SPFA算法有两种优化算法 SLF 和 LLL SLF:Small Label First 大概是双向队列? 如果要加入的元素v的距离dis[v]比当前的队首元素dis[q[head]]小的话,那么就把当前元素插到队首。 如果是手打队列的话,就先head-2,再q[head+1]=v; LLL:Large Label Last 如果队列q的队首元素为x,队列中所有元素的平均距离为di

ywq12138的博客 581

DMA学习笔记

DMA(direct memory access,直接内存访问),是一种避开CPU,可以直接对外设和内存进行访问的技术,可以实现外设与内存、内存之间、外设之间的数据的访问和搬移。

weixin_46220498的博客 3111

优化版的Dijkstra和spfa写法相似的原因以及区别

众所周知,Dijkstra先将所有节点到起点的距离设为正无穷,再将起点到起点的距离设为0,通过n次循环,每次循环找出距离起点最短的点,用该点更新它的相邻节点到起始点的距离,这样n次循环之后即可确定终点到起点的最短距离是多少。而每次寻找距离起点最短距离的点若不使用最小堆来维护,则需要O(n)的时间,若使用堆则只需要O(1),这就是堆优化版的Dijkstra。

m0_62378181的博客 966

Full Range && Limit Range

Full Range && Limit Range1 Full range和Limit Range定义2 为什么会需要Limit Range3 用Full range去显示limit Range图片4 YUV转RGB5 额外 1 Full range和Limit Range定义 我们知道,对于RGB和YUV的色彩空间来说,有个位深(bit-depth)的概念;位深是指记录图像每个像素的色彩通道时所使用的bit数,常见的RGB888,YUV420-8bit。以RGB888为例,其代表R G B

zjhcj1的博客 1万+

SoulX-FlashHead 加速实践,提升3倍。

SoulX-FlashHead 加速实践,提升3倍。

jacke121的专栏 220

浅谈spfa几个优化

优化一:每次更新节点时,记录当前走的这条路径的节点数,当节点数大于n时,有负环,退出。注意,这里与常规的节点被更新n次以上退出不一样,效率比常规高。 优化二:双端队列SLF优化。当当前节点到起点距离小于队首的时候,将此点插入队首,否则,正常插入队尾。可能咋一看感觉这种优化可能被用到的机会很少,但很可能正好解决掉了专门卡spfa的数据以及网格图。 优化三:与优化二类似,但改为小于队列元...

ba82586628365094的博客 411

22、预条件技术:矩阵分解与多项式预条件器

本文系统介绍了预条件技术中的不完全分裂法、多项式预条件器和近似逆预条件器。内容涵盖矩阵分解的基本原理、不完全LU和Cholesky分解的实现方法、基于填充水平和阈值策略的改进技术,以及多项式和近似逆预条件器的数学基础与应用。通过算法流程图和表格对比,展示了各类预条件器的适用场景与优缺点,同时探讨了其在迭代求解中的关键作用和未来发展方向。

theta的博客 94

浅谈Spfa

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

月殇 896

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

浅谈最短路-SPFA算法

SPFA(Shortest Path Faster Algorithm)(队列优化) ·优点       SPFA算法是求单源最短路的一种算法,解决了Dijkstra算法无法应用于给定的图存在负权边的问题,而且其复杂度要小于Bellman-Ford算法,是比较高的一种最短路算法。 ·原理      我们用数组d记录每个结点的最短路径估计值,而且用邻接表来存储图G

优快云_YingHui的博客 589

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

浅谈最短路之——Bellman-Ford和SPFA

       最短路算法中,精确找到最短路最常用的办法莫过于Bellman-Ford以及其优化后的SPFA算法。     Bellman-Ford算法较Dijkstar算法可以应用于含负边权的图,对于一个图G(V,E),其中V为点集,E为边集,源点s,首先定义dis数组,dis[i]为i到s的最短距离。枚举每一条边(u,v),如果dis[u]+w[u,v]&lt;dis[v],就更新dis[v]...

Michael_GLF的博客 910

浅谈SPFA判负环(依旧是对某一天思考的记录)以及对于SPFA的一点点扩展

有一天,我正在做这道题目,做法就不讲了,在判负环的时候(当然这道题目0环也要判,后面再讲),我引发除了对SPFA这个队列优化的经过的边数的深入疑惑。 由于队列优化中已经插入的点不再插入,所以,这个会导致队列中的点的层数无法呈现阶段性增长,可能会导致判负环的时候经过的边数出一点问题,但在今天的思考中,我终于是又想明白了一点点。 首先讲讲如何判负环吧,因为上篇浅谈SPFA中讲到,一个正常的SPFA路径最多只有n−1n-1n−1条边,超过就是存在负环了(经过一个点两次以上)。那么只需要记录一个depdepdep(

蒟蒻QMQ 237

浅谈SPFA(队列优化的Bellman-Ford算法)

浅谈SPFA及其优化 SPFA的前提—–Bellman-Ford算法 SPFA的核心思想 SPFA详解 SPFA的优化 图中负环的判断 一、Bellman-Ford算法 Bellman-Ford 算法是一种用来求单源最短路径的一种算法,可以用于负边权上,但是如果有负环的话就没办法了(有负环可能算的出来吗?) 优点:便于理解,代码简短; ...

weixin_30316097的博客 347

浅谈SPFA(没有特别的探讨,只是对某天晚上的思考做个记录)

文章目录参考文献最短路推论Bellman-ford 算法SPFA错误的证明方法卡法 参考文献 https://www.cnblogs.com/jason2003/p/7224580.html 一下代码均抄自此大佬的博客。 最短路推论 对于一个最短路,最多经过n−1n-1n−1条边,如果超过这个,则必然重复经过一个点,则必然存在负环,证毕。 Bellman-ford 算法 通过上面,我们不难知道,我们可以用dp思想,设f[i]f[i]f[i]表示111到iii在最多经过jjj条边的最短路径,那么,我们只需要在

蒟蒻QMQ 704

[转]浅谈dijkstra堆优化

众所周知的,dijkstra是图论算法中求单源最短路的一种简单求法。可能有人会说SPFA比dijkstra要实用,而且可以用于求存在负边权的情况,但是dijkstra有着他的优点——其运行速度上优于SPFA。(PS.需要堆进行优化。) 我们先看一道经典(水)题: 平面上有n个点(n<=100),每个点的坐标均在-10000~10000之间。其中的一些点之间有连线。 若有连线,...

weixin_30345055的博客 123

浅谈spfa算法

对Bellman-Ford算法进行优化->SPFA算法 注意到Bellman-Ford算法实际上做了很多无用功。因为每次它都把所有的边枚举一次,而有一些边在上一次枚举中,起始端顶点都没有更新,那么在这一次枚举中,肯定不会进行松弛。那么我们可以使用一个队列来进行活跃点的维护。我们定义在这个队列里的每个元素x都必须满足:d[x]被更新,但是未利用d[x]去更新其它的点。那么初始时把起始点1放进队列里

qq_35786326的博客 439

浅谈单源最短路径(Spfa,Dijkstra)

Spfa Spfa是类似bfs的一种图论方法,运用队列更新dis[i],求得图中1~n的最短路径。 Spfa中用到dis[i]表示图中每一点距离起点的长度,bz[i]用来记录编号为i的点是否入队,a[x,y]表示图中x~y之间的距离,b[x,i]表示编号为x的点的第i条边的终点,每次更新这个终点到起点的距离,以当前入队的点来更新,最后求出答案。 tov[i]表示编号为i的边的终...

cdy1206473601的博客 527
上一篇: P1656 炸铁路 题解
下一篇: AtCoder Beginner Contest 377 D题题解
灶龙
博客等级 码龄4年 126粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值