Bellman-ford算法

Bellman-ford算法

要说求最短路径可以用之前学的Dijkstra,但是Dijkstra 不能处理负权边,更不能处理负环;Bellman-Ford 可以!

在图论体系中:

  • Dijkstra:贪心、快、只能正权
  • Bellman-Ford:迭代松弛、稳、支持负权、可判负环(高级图论必备)

松弛操作

给定一条边:u → v,边权 w

松弛公式

复制代码
if(dist[v] > dist[u] + w)
	dist[v]=dist[u]+w

说明:走 u 中转到 v,比原来 v 的路径更短,更新最短路。

发现一条更近的路,就更新距离

Bellman-Ford 不挑点、不挑边,暴力对所有边反复松弛

判断负环

存在一个环:绕一圈总边权和为负数

可以无限绕环,路径长度无限变小 → 没有最短路

设图一共有 n 个点。

无负环的图中:

任意两点的最短路径,最多经过 n-1 条边

比如 3 个点:最短路径最多 2 条边。

所以:

  • 第 1 轮松弛:更新所有「1条边」的最短路
  • 第 2 轮松弛:更新所有「2条边」的最短路
  • ......
  • 第 n-1 轮松弛:更新所有最长合法最短路

n-1 轮之后,所有点的最短路一定已经收敛,不会再更新 ,如果第 n 轮还能成功松弛,就能判断有负环

算法流程

  1. 初始化:所有点距离无穷大,起点距离为 0
  2. 迭代 n-1 轮 :每一轮遍历 所有 m 条边 做松弛
  3. 第 n 轮校验:还能松弛 = 存在负权环

时间复杂度:O(n*m)

适合:点数小、需要处理负权、判负环、差分约束问题。

Dijkstra、Bellman-ford与SPFA 的对比

整个最短路体系层级:

  • Bellman-Ford:暴力松弛、最稳、可负权、可负环、最慢
  • SPFA:队列优化版 Bellman-Ford
  • Dijkstra:贪心堆优化、只能正权、最快

Bellman-Ford 是理论基石,SPFA 是进行了队列优化。

Dijkstra 需要「遍历某个点的所有出边」,必须用邻接表/二维数组;Bellman-Ford 不需要定点遍历,它每一轮直接遍历「整张图的所有边」

判断负环模板

三个一维数组:u[](起点)、v[](终点)、w[](边权),

复制代码
#include<bits/stdc++.h>
using namespace std;
const int N=6005;
const int INF=0x3f3f3f3f;
int u[N],v[N],w[N],dist[N];
int n,m,cnt;
bool bellman(){
	for(int i=1;i<=n;i++){
		dist[i]=INF;
	}
	dist[1]=0;
	for(int i=1;i<n;i++){
		bool ok=false;
		for(int j=1;j<=cnt;j++){
			if(dist[u[j]]!=INF&&dist[v[j]]>dist[u[j]]+w[j]){
				dist[v[j]]=dist[u[j]]+w[j];
				ok=true;
			}
		}
		if(!ok){
			break;
		}
	}
	for(int j=1;j<=cnt;j++){
		if(dist[u[j]]!=INF&&dist[v[j]]>dist[u[j]]+w[j]){
			return true;
		}
	}
	return false;
}
int main(){
	int t;
	cin>>t;
	while(t--){
		cnt=0;
		cin>>n>>m;
		for(int i=1;i<=m;i++){
			int a,b,c;
			cin>>a>>b>>c;
			if(c>=0){
				cnt++;
				u[cnt]=a;
				v[cnt]=b;
				w[cnt]=c;
				cnt++;
				u[cnt]=b;
				v[cnt]=a;
				w[cnt]=c;
			}
			else{
				cnt++;
				u[cnt]=a;
				v[cnt]=b;
				w[cnt]=c;
			}
		}
		if(bellman()){
			cout<<"YES"<<endl;
		}
		else{
			cout<<"NO"<<endl;
		}
	}
	return 0;
}
相关推荐
叠层归一研究院20 分钟前
基于区分本源的此刻存在唯一性本体论推演
人工智能·算法
luj_176820 分钟前
尾椎藏今生记忆?骨盆对应不确定性
开发语言·网络·c++·经验分享·算法
深圳多奥智能一卡(码、脸)通系统22 分钟前
智能梯控SDK可直接用于第三方开发对接的接口文档说明书
服务器·前端·算法
裕晟资质规划10 小时前
武器装备科研生产单位保密资质申请方法论:条件模型与流程拆解
人工智能·算法
en.en..11 小时前
C语言 标准输入 / 输出缓冲区
算法
吃好睡好便好13 小时前
查找函数的使用
学习·算法·matlab·生活·查找函数
学习星球13 小时前
单调栈——从“找下一个更大的“到柱状图中的最大矩形
数据库·c++·算法·leetcode·xcode
靠沿14 小时前
贪心算法专题(二)
算法·贪心算法
猎头南楼15 小时前
具身智能模型部署方向的能力要求与技术栈梳理
人工智能·深度学习·算法