news 2026/5/1 10:55:16

最短路(Spfa)(信息学奥赛一本通- P1382)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
最短路(Spfa)(信息学奥赛一本通- P1382)

【题目描述】

给定 M 条边, N 个点的带权无向图。求 1到 N 的最短路。

【输入】

第一行:N,M(N<=100000,M<=500000);

接下来M行3个正整数:ai,bi,ci表示ai,bi之间有一条长度为ci的路,ci<=1000。

【输出】

一个整数,表示 1 到 N 的最短距离。

【输入样例】

4 4 1 2 1 2 3 1 3 4 1 2 4 1

【输出样例】

2

【提示】

【样例解释】

注意图中可能有重边和自环,数据保证 1 到 N 有路径相连。

0. 题目概要

给定N个点 (N<=10^5) 和M条边 (M<=5*10^5) 的带权无向图。

求从点 1 到点N的最短距离。

提示:虽然题目指定用 SPFA,但在实际工程或比赛中,对于正权图,堆优化 Dijkstra 是更稳定的选择。

1. 算法解析

1.1 SPFA 的核心逻辑

SPFA是 Bellman-Ford 的队列优化版。

  • 核心思想:只有“变短了”的点,才有可能去更新它的邻居。

  • 实现机制

    1. 用队列维护所有“距离被更新且尚未处理”的节点。

    2. 取出队首节点u,取消标记。

    3. 遍历u的所有出边 (u, v, w)。

    4. 松弛操作:如果dis[v] > dis[u] + w,则更新dis[v]

    5. 如果v更新了且不在队列中,将v入队并标记。

1.2 空间与时间

  • 空间:由于是无向图,存图时需要建双向边,因此边数组的大小必须开到2*M。本题 M=500,000,数组至少要开1,000,000。

  • 时间:SPFA 的平均时间复杂度是O(kM)(k为常数,约 2~4)。但在最坏情况下(如网格图)会退化为O(NM)。本题数据通常较弱,SPFA 可过。

2. 易错点

  1. 数组越界:这是无向图最短路最容易挂的地方,M是 50 万,vtex,nxt,wt必须开到100 万以上

  2. IO 瓶颈:M很大,输入数据多,建议使用快读或关闭同步流ios::sync_with_stdio(false); cin.tie(0);

  3. 重边与自环:SPFA 的松弛操作if(dis[v] > dis[u] + w)天然能处理重边(会自动选短的那条)和自环(不会死循环),无需特殊处理。

3. 完整代码

//题目写了spfa 我们就spfa #include <iostream> #include <cstring> #include <queue> using namespace std; int n,m; const int maxn=100010; const int maxm=1100000; int h[maxn]; int vtex[maxm]; int nxt[maxm]; int wt[maxm]; int idx; int dis[maxn]; int is_used[maxn];//标记每个点是否在队列中 queue<int> q; void spfa(int s){ dis[s]=0;//起点到自己距离为0 int tmp=s; q.push(tmp);//起点入队 is_used[tmp]=1;//打上标记 while(!q.empty()){ tmp=q.front();//访问队首 q.pop();//出队 is_used[tmp]=0;//取消标记 int p=h[tmp];//tmp头指针 while(p!=-1){//遍历tmp所有邻接点 //如果该邻接点到源点距离大于 tmp到源点距离+边权 if(dis[vtex[p]]>dis[tmp]+wt[p]){ //就更新该邻接点到源点距离 dis[vtex[p]]=dis[tmp]+wt[p]; //如果该邻接点不在队中就入队并打上标记否则不用理会 if(is_used[vtex[p]]==0){ q.push(vtex[p]); is_used[vtex[p]]=1; } } p=nxt[p];//更新指针 } } } void addedge(int u,int v,int w){ vtex[idx]=v; nxt[idx]=h[u]; wt[idx]=w; h[u]=idx++; } int main(){ ios::sync_with_stdio(false); cin.tie(0); cin>>n>>m; memset(h,-1,sizeof(h)); //邻接表存图 for(int i=1;i<=m;i++){ int a,b,c; cin>>a>>b>>c; addedge(a,b,c);//无向即双向路 addedge(b,a,c); } memset(dis,0x3f,sizeof(dis));//初始化所有点到1距离为无穷 spfa(1); cout<<dis[n]; return 0; }

4. 总结

这道题是 SPFA 的入门模板题。

  • 优点:代码比堆优化 Dijkstra 短,逻辑简单,能处理负权边。

  • 缺点:极其不稳定,容易被出题人卡tle。

  • 策略:如果题目没明确说“可能有负权边”,尽量首选 Dijkstra。但本题指名道姓要 SPFA,那就用,数组开够即可。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 6:30:15

STARsolo单细胞RNA测序分析实战指南

STARsolo单细胞RNA测序分析实战指南 【免费下载链接】STAR RNA-seq aligner 项目地址: https://gitcode.com/gh_mirrors/st/STAR 技术核心原理 STARsolo作为STAR比对工具的内置单细胞RNA测序分析模块&#xff0c;采用一体化的设计理念&#xff0c;将传统分析流程中的多…

作者头像 李华
网站建设 2026/5/1 6:47:59

移动端开发者的福音:远程调用云端Z-Image-Turbo服务全指南

移动端开发者的福音&#xff1a;远程调用云端Z-Image-Turbo服务全指南 作为一名移动应用开发者&#xff0c;你是否曾想过在APP中集成炫酷的AI图像生成功能&#xff0c;却苦于移动设备性能不足&#xff1f;Z-Image-Turbo作为阿里通义实验室开源的6亿参数图像生成模型&#xff0…

作者头像 李华
网站建设 2026/5/1 8:16:31

Pixi-Live2D-Display终极指南:快速集成生动虚拟角色

Pixi-Live2D-Display终极指南&#xff1a;快速集成生动虚拟角色 【免费下载链接】pixi-live2d-display A PixiJS plugin to display Live2D models of any kind. 项目地址: https://gitcode.com/gh_mirrors/pi/pixi-live2d-display 想要为你的网站或应用添加令人惊艳的L…

作者头像 李华
网站建设 2026/4/30 10:28:31

开源社区热门OCR项目:CRNN镜像GitHub星标破5K

开源社区热门OCR项目&#xff1a;CRNN镜像GitHub星标破5K &#x1f4d6; 项目简介 在数字化转型加速的今天&#xff0c;OCR&#xff08;光学字符识别&#xff09;技术已成为信息自动化处理的核心工具之一。从扫描文档到发票识别&#xff0c;从车牌提取到手写笔记转录&#xf…

作者头像 李华
网站建设 2026/5/1 8:02:43

告别熬夜赶稿的烦恼,拥抱智能生成的高效,让您的开题报告成为您学术生涯中最闪亮的一笔!

对于每一位踏上学术研究征程的学子而言&#xff0c;开题报告是整个研究旅程中至关重要、却又令人倍感压力的第一步。它不仅是向导师和评审委员会展示您研究能力的“敲门砖”&#xff0c;更是为后续所有研究工作划定方向、奠定基础的“总蓝图”。一份优秀的开题报告&#xff0c;…

作者头像 李华
网站建设 2026/5/1 7:47:21

OCR识别新突破:CRNN在模糊图像中的表现

OCR识别新突破&#xff1a;CRNN在模糊图像中的表现 &#x1f4d6; 项目简介 光学字符识别&#xff08;OCR&#xff09;作为连接物理世界与数字信息的关键技术&#xff0c;广泛应用于文档数字化、票据识别、车牌读取、智能办公等场景。传统OCR系统在清晰、规整的印刷体文字上表现…

作者头像 李华