图论-最短路 Bellman-Ford算法

文章目录

Bellman-Ford算法

此算法是基于松弛操作 的单源最短路算法。

e[u]存u点的出边的邻边和边权,d[u]存u点到源点的距离。

  • 1.初始化,d[s]=0,d[其他点]=INT_MAX。
  • 2.执行多轮循环,对所有边都尝试进行一次松弛操作。
  • 3.当一轮中没有成功的松弛操作时,算法停止。

如图,3为源点

代码展示

cpp 复制代码
struct edug{
	int v,w;
}; 
vector<edge>e[N];
int d[N];
bool Bellman-Ford(int s)
{
	//把所有点到源点的距离初始为无穷大
	memset(d,0x3f3f3f,sizeof d);
	d[s]=0;//源点到自身的距离为0
	bool f;//标记是否有松弛操作
	for(int i=1;i<=n;i++)//n轮操作 
	{
		f=false;
		for(int u=1;u<=n;u++)//n个点 
		{
			if(d[u]==0x3f3f3f)continue;
			for(auto x:ed[u])//遍历u的出边 
			{
				int v=x.v,w=x.w;
				if(d[u]+w<d[v])
				{
					d[v]=d[u]+w;
					f=true;
				}
			}
		}
		if(!f)break;//没有得到更新就退出 
	 } 
	 return f;//第n轮=true则有环 
}

int main()
{
	cin>>n>>m>>s;
	for(int i=0;i<m;i++)
	{
		cin>>a>>b>>c;
		e[a].push_back({b,c});
	}
	return 0;
 } 

优点:

可以正确处理负边权

可以判负环 ,如果n轮循环后仍存在能松弛的边,则说明存在负环。

时间复杂度:O(nm)

SPFA优化

我们可以想到只有本轮被更新的点,其出边才有可能引起下一轮的松弛操作,因此用队列来维护被更新的点的集合。

vis[u]标记u点是否在队内,cnt[v]记录边数,判负环。

  • 1.初始化,s入队,并标记s在队内,d[s]=0,d[其他点]=INT_MAX
  • 2.从队头弹出u点,标记u不在队内
  • 3.枚举u的所有出边,执行松弛操作 ,记录s到v的边数,并判负环。如果v不在队内则把v 压入队尾,并标记
  • 重复2,3操作,直到队列为空。

代码展示

cpp 复制代码
struct edug{
	int v,w;
}; 
vector<edge>e[N];
int d[N];
queue<int>q;
bool spfa(int s)
{
	memset(d,0x3f3f3f,sizeof d);
	d[s]=0,vis[s]=1;
	q.push(s);
	while(q.size())
	{
		int u=q.front();
		q.pop();
		vis[u]=0;
		for(auto x:e[u])
		{
			int v=x.v,w=x.w;
			if(d[u]+w<d[v])
			{
				d[v]=d[u]+w;
				cnt[v]=cnt[u]+1;
				if(cnt[v]>=n)
				return true;
				if(!vis[v])q.push(v),vis[v]=1;
			}
		}
	}
	return false;
}

路径记录与传输

cpp 复制代码
void dfs_path(int u)
{
	if(u==1)
	{
		cout<<u<<" ";
		return ;
	}
	dfs_path(pre[u]);
	cout<<u<<" ";
}
相关推荐
Youndry11 分钟前
二叉搜索树的最小绝对差
算法
一方热衷.13 分钟前
YOLOv8/YOLOv11 C++ OpenCV DNN推理
c++·opencv·yolo
泥泞开出花朵32 分钟前
LRU缓存淘汰算法的详细介绍与具体实现
java·数据结构·后端·算法·缓存
ankleless1 小时前
C语言(02)——标准库函数大全(持续更新)
c语言·开发语言·算法·标准库函数·零基础自学
玖剹1 小时前
Linux文件系统:从内核到缓冲区的奥秘
linux·c语言·c++·笔记·ubuntu
补三补四1 小时前
Shapley与SHAP
大数据·人工智能·算法·机器学习·数据分析
KarrySmile2 小时前
Day17--二叉树--654. 最大二叉树,617. 合并二叉树,700. 二叉搜索树中的搜索,98. 验证二叉搜索树
数据结构·算法·二叉树·二叉搜索树·合并二叉树·最大二叉树·验证二叉搜索树
凤年徐2 小时前
【数据结构与算法】21.合并两个有序链表(LeetCode)
c语言·数据结构·c++·笔记·算法·链表
程序员老冯头2 小时前
第三十二节 MATLAB函数
数据结构·算法·matlab
lifallen2 小时前
hadoop.yarn 带时间的LRU 延迟删除
java·大数据·数据结构·hadoop·分布式·算法