单源最短路-SPFA版本 学习笔记
关于SPFA
它死了。
NOI2018第一题 归程,很多选手使用了一种广为人知一种求最短路的算法——SPFA,最后,由于SPFA算法被造数据的人卡掉了,结果:
希望大家不要重蹈覆辙。
这一题的正解是,但是,我们先讲讲SPAFA,毕竟是我还是一个普及组的蒟蒻,而普及组不会被卡SPFA。
关于Dijstra的题解可以点击这里。
算法实质
关于SPFA,其实就是一个松弛计划。说白了,就是这样的:
首先令为第个点到号点的最短路,那么,。
接下来我们遍历这张图(这里用dfs,但代码一般是用bfs更快)。
先遍历号点,那么。然后继续就可以了。
接下来是重点我们回到号点这是3号点已经有值了,但是原来的的值是,但是,我们遍历过来的时候的值为,比原来的小,这是我们就可以把就可以了,这样这张图的遍历就完成了。
算法缺点
如果出题人有意造数据,你遍历了这张图,先从第一个点开始遍历,然后遍历完这张图,把所有的点都得到了一个值,然后回来发现,这个值都是加的,这样就会浪费掉大量的时间,就会被卡成的复杂度了,接下来就是TLE了,所以,这里建议使用广度优先搜索。
代码实现
这里用链式前向星来存图以及BFS。
关于BFS
#include<cstdio>//SPAFA #include<queue>//采用链式前向星 #include<cstring>//BFS #define maxn 500039 using namespace std; int to[maxn],nex[maxn],head[maxn],q[maxn],k; int n,m,i,f,t,s,qq; int ans[maxn]; void add(int x,int y,int z){ to[k]=y; q[k]=z; nex[k]=head[x]; head[x]=k; k++; return; } void bfs(int x){ queue<int> qq; int now; ans[x]=0; qq.push(x); while(!qq.empty()){ int cur=qq.front(); qq.pop(); for(int i=head[cur];i!=-1;i=nex[i]){ if( ans[cur] + q[i] >= ans[to[i]] ) continue; ans[to[i]] = ans[cur] + q[i]; qq.push(to[i]); } } return; } int main(){ scanf("%d%d%d",&m,&n,&s); memset(ans,0x3f,sizeof(ans)); memset(head,-1,sizeof(head)); memset(nex,-1,sizeof(nex)); ans[s]=0; for(i=1;i<=n;i++){ scanf("%d%d%d",&f,&t,&qq); add(f,t,qq); } bfs(s); for(int i=1;i<=m;i++) if(ans[i]==0x3f3f3f3f) printf("2147483647 "); else printf("%d ",ans[i]); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具