SPFA求最短路——Bellman-Ford算法的优化
SPFA 算法是 Bellman-Ford算法 的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环。SPFA 最坏情况下复杂度和朴素 Bellman-Ford 相同,为 O(VE),但是一般情况下他的复杂度还是很优秀的,为O(mn),其中稀疏图中m约等于2,稠密图...关于SPFA:他死了,n为边数(值得一提,有的非常bt的数据会故意卡spfa不让你过 比如菊花图,蒲公英图什么的)
算法大意:设立一个队列来保存所有待优化的结点,先初始化所有最短路径,然后从起点开始不断遍历每一条边,不断进行松弛操作,再用已经优化完的结点去更新队列中其他节点
重要变量解释:
dis表示从源点到点i的最短路径
vis表示这个点目前是否在队列里
head表示这个点所有出边中序号最大的那一条
代码:
#include<cstdio> #include<iostream> #include<cstdlib> #include<iomanip> #include<cmath> #include<cstring> #include<string> #include<algorithm> #include<time.h> #include<queue> using namespace std; typedef long long ll; typedef long double ld; typedef pair<int,int> pr; const double pi=acos(-1); #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define Rep(i,u) for(int i=head[u];i;i=next[i]) #define clr(a) memset(a,0,sizeof a) #define pb push_back #define mp make_pair #define fi first #define sc second ld eps=1e-9; ll pp=1000000007; ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;} ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;} ll read(){ll ans=0;char last=' ',ch=getchar();while(ch<'0' || ch>'9')last=ch,ch=getchar();while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();if(last=='-')ans=-ans;return ans; } //head const int inf=2147483647; int n,m,s;//点的个数、有向边的个数、出发点的编号 int dis[10005],vis[10005],head[10005],cnt; //dis表示从源点到点i的最短路径 //vis表示这个点目前是否在队列里 //head表示这个点所有出边中序号最大的那一条 struct Edge {int next,dis,to; }edge[9999999];queue <int> q;inline void add_edge(int from,int to,int dis) {cnt++;edge[cnt].next=head[from];edge[cnt].to=to;edge[cnt].dis=dis;head[from]=cnt; }//存边 void spfa() {rep(i,1,n)dis[i]=inf,vis[i]=0;//初始化 dis[s]=0;vis[s]=1;//把始点标记成在队列中 q.push(s);//入队 while(!q.empty()){int u=q.front();//队首的点 q.pop();//出队 vis[u]=0;//标记成已经出队 for(int i=head[u];i;i=edge[i].next)//遍历每一条边 {int v=edge[i].to;if(dis[v]>dis[u]+edge[i].dis){dis[v]=dis[u]+edge[i].dis;//松弛操作 if(!vis[v]){q.push(v);vis[v]=1;}//入队 }}} }int main() {scanf("%d %d %d",&n,&m,&s);for(int i=1;i<=m;++i){int u,v,d;//第i条有向边的出发点、目标点和长度scanf("%d %d %d",&u,&v,&d);add_edge(u,v,d);}spfa();for(int i=1;i<=n;++i){if(i==s) printf("0 ");//自己到自己为0 else printf("%d ",dis[i]);}return 0; }
感觉和Dijkstra差不多,但其实他俩区别还是很大的
Dijkstra是找到从当前节点所有出边中找到最短的,然后用这条最短边继续更新其他路径
而SPFA是对当前节点的所有出边不断进行松弛操作,然后用更新完的边去更新其他结点的其他边
(其实好像挺像的)
转载于:https://www.cnblogs.com/lcezych/p/10759139.html
SPFA求最短路——Bellman-Ford算法的优化相关推荐
- c语言bellman算法,求 最短路径中BELLMAN FORD算法实现的C程序
匿名用户 1级 2010-06-01 回答 //这个是邻接表 typedef struct oo { int len,num; struct oo *next; } link; typedef str ...
- bellman ford 算法 判断是否存在负环
Flyer 目录视图 摘要视图 订阅 微信小程序实战项目--点餐系统 程序员11月书讯,评论得书啦 Get IT技能知识库,50个领域一键直达 关闭 bellman for ...
- Bellman Ford算法详解
一.用途 1. Bellman Ford算法是解决拥有负权边最短路问题的方法之一.还有一种方法是SPFA算法. 2. 二者相比,SPFA算法在效率方面是优于Bellman Ford算法的.但在某些情况 ...
- bellman - ford算法c++
(最短路III)bellman - ford算法(适用于含负权边的图) 注意:用该算法求最短路,在有边数限制的情况下可以存在负权回路!且对所走的边的数量有要求时只能用该算法实现! 解析:因为如果没有边 ...
- Bellman ford算法(贝尔曼·福特算法)
Bellman - ford算法是求含负权图的单源最短路径的一种算法,效率较低,代码难度较小.其原理为连续进行松弛,在每次松弛时把每条边都更新一下,若在n-1次松弛后还能更新,则说明图中有负环,因此无 ...
- Bellman——Ford算法
Bellman--Ford 算法介绍 思路讲解 案例分析与代码实现 案例分析 代码实现 优先队列优化(SPFA) 优化原理 代码实现 算法介绍 我们知道Dijkstra算法只能用来解决正权图的单源最短 ...
- AcWing 851. spfa求最短路(解决负边权最短路)
题目链接 https://www.acwing.com/problem/content/853/ 思路 就是SPFA求最短路的模板,其思路大概是我们要更新所有能被松弛的边,然后更新松弛的边的边,然后就 ...
- LeetCode 787. K 站中转内最便宜的航班(图/Bellman Ford算法)
文章目录 贝尔曼-福特算法(Bellman-Ford) 简介 算法思想 算法执行过程 应用 题目描述 分析 代码 LeetCode 787. K 站中转内最便宜的航班 题目描述 Bellman For ...
- 图解Bellman Ford算法
Bellman Ford 单源最短路径算法[中字] Bellman Ford 单源最短路径算法[中字]_哔哩哔哩_bilibili 贝尔曼-福特算法(Bellman–Ford algorithm )油 ...
- 851. spfa求最短路 Java题解 (spfa)
输入样例: 3 3 1 2 5 2 3 -3 1 3 4 输出样例: 2 算法思路: spfa最短路算法是对bellmanFord算法的优化,用于求单源最短路间的带负权的算法,一般时间复杂度为O(m) ...
最新文章
- [图示]营销理论:不同时代的用户如何接受一个新事物?
- Android --- 很好用的时间选择器
- log4j 禁止类输出日志_log4j 2过滤spring日志遇到的问题
- Android mock for循环,Android单元测试(五):依赖注入,将mock方便的用起来
- 信息学奥赛一本通C++语言——1119:矩阵交换行
- Hadoop2.6.0中YARN底层状态机实现分析
- 【06年博文搬家】一个修改时间的批处理程序
- python-线程互斥锁与递归锁
- Unity3d 好友管理系统
- Java校招基础知识总结(横扫BAT,就业经验交流会演讲稿)
- MySQL专题系统归纳快速上手(常用cmd命令,常用函数汇总,SQL语句精讲带示例)适用初学、用法速查
- KubeEdge 王泽锋:只有代码没有生命力,凝聚开发者的社区才能活力无限 I OpenTEKr 大话开源 Vol.8
- 三元运算符(三目运算符)
- 零基础 Python学习
- POND:高效的 Python 通用对象池库
- 2005年的网易邮箱长什么样的?
- C++11 新特性。
- SpringBoot整合微信支付开发在线教育视频网站(完整版)
- Android webview 自动登陆新浪微博实现(原理)
- AE开发笔记(二)制图输出