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算法的优化相关推荐

  1. c语言bellman算法,求 最短路径中BELLMAN FORD算法实现的C程序

    匿名用户 1级 2010-06-01 回答 //这个是邻接表 typedef struct oo { int len,num; struct oo *next; } link; typedef str ...

  2. bellman ford 算法 判断是否存在负环

    Flyer 目录视图 摘要视图 订阅 微信小程序实战项目--点餐系统        程序员11月书讯,评论得书啦        Get IT技能知识库,50个领域一键直达 关闭 bellman for ...

  3. Bellman Ford算法详解

    一.用途 1. Bellman Ford算法是解决拥有负权边最短路问题的方法之一.还有一种方法是SPFA算法. 2. 二者相比,SPFA算法在效率方面是优于Bellman Ford算法的.但在某些情况 ...

  4. bellman - ford算法c++

    (最短路III)bellman - ford算法(适用于含负权边的图) 注意:用该算法求最短路,在有边数限制的情况下可以存在负权回路!且对所走的边的数量有要求时只能用该算法实现! 解析:因为如果没有边 ...

  5. Bellman ford算法(贝尔曼·福特算法)

    Bellman - ford算法是求含负权图的单源最短路径的一种算法,效率较低,代码难度较小.其原理为连续进行松弛,在每次松弛时把每条边都更新一下,若在n-1次松弛后还能更新,则说明图中有负环,因此无 ...

  6. Bellman——Ford算法

    Bellman--Ford 算法介绍 思路讲解 案例分析与代码实现 案例分析 代码实现 优先队列优化(SPFA) 优化原理 代码实现 算法介绍 我们知道Dijkstra算法只能用来解决正权图的单源最短 ...

  7. AcWing 851. spfa求最短路(解决负边权最短路)

    题目链接 https://www.acwing.com/problem/content/853/ 思路 就是SPFA求最短路的模板,其思路大概是我们要更新所有能被松弛的边,然后更新松弛的边的边,然后就 ...

  8. LeetCode 787. K 站中转内最便宜的航班(图/Bellman Ford算法)

    文章目录 贝尔曼-福特算法(Bellman-Ford) 简介 算法思想 算法执行过程 应用 题目描述 分析 代码 LeetCode 787. K 站中转内最便宜的航班 题目描述 Bellman For ...

  9. 图解Bellman Ford算法

    Bellman Ford 单源最短路径算法[中字] Bellman Ford 单源最短路径算法[中字]_哔哩哔哩_bilibili 贝尔曼-福特算法(Bellman–Ford algorithm )油 ...

  10. 851. spfa求最短路 Java题解 (spfa)

    输入样例: 3 3 1 2 5 2 3 -3 1 3 4 输出样例: 2 算法思路: spfa最短路算法是对bellmanFord算法的优化,用于求单源最短路间的带负权的算法,一般时间复杂度为O(m) ...

最新文章

  1. bootstrapdatetimepicker 隐藏触发 bootstrap modal隐藏事件
  2. CUDA编程快速入门教程
  3. ps -aux|grep 详细信息
  4. SpaceVim 语言模块 dart
  5. 访问chm文件出现“已取消到该网页的导航”的解决方法
  6. [小北De编程手记] : Lesson 02 - Selenium For C# 之 核心对象
  7. 计算机网络实验arp协议分析,计算机网络ARP地址协议解析实验报告
  8. MyBatis-generator使用,Example缺少分页问题解决
  9. eBPF学习记录(三)使用BCC开发eBPF程序
  10. 大数据Spark(五十二):Structured Streaming 事件时间窗口分析
  11. 小程序解析富文本(支持视频,支持微信编辑器,支持135编辑器富文本样式)
  12. 技术杂谈-再谈软硬SDN(1)
  13. Mac 取消系统更新的红点——强迫症晚期患者
  14. bas64-FileReader-base64-11.9-01
  15. 踩坑实录——多光谱影像(.tif)输入深度学习网络训练
  16. SSM实现考研助手系统
  17. 20岁不考证,25岁不加班,30岁不熬夜,40岁你还有工作吗?
  18. BERT embedding 降维--BERT whitening
  19. 【8086汇编基础】05--常用函数库文件--emu8086.inc
  20. 小米盒子看直播的简单方法

热门文章

  1. IPLAT62--后台返回提示参数
  2. 数学6年级测试软件,苏教版数学六年级下册2018年小学六年级毕业测试试卷(无答案).doc...
  3. 计算机网络滑动窗口机制编程,计算机网络之滑动窗口机制
  4. java百度结果的正则表达式_java正则表达式
  5. winform 让他间隔一段时间 执行事件 且只执行一次_记一次golang定时器引发的诡异错误...
  6. python tcl 控件_在Python中解析TCL列表
  7. ireport使用参考
  8. 红帽安装Oracle步骤
  9. Spark机器学习(7):KMenas算法
  10. 无刷新三级联动(ajax)(转)