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;
}
相关推荐
qq_410194297 小时前
.NET 8.0 下基于 PaddleOCRSharp 的离线文字识别落地指南
算法·.net
Omics Pro7 小时前
1个月2轮融资!长寿虚拟细胞
数据库·人工智能·算法·机器学习·自然语言处理
residual_fan7 小时前
航空发动机故障诊断专用智能体(六):实际机队健康管理中的应用考量与展望
人工智能·算法·数据挖掘·数据分析
hansang_IR7 小时前
【讲解】CSP-S2026 第一轮初赛
c++·算法
hanlin037 小时前
刷题笔记:力扣第76题-最小覆盖子串
笔记·算法·leetcode
Zane19947 小时前
比较排序跑不出O(nlogn)是数学上证明过的,计数、桶、基数排序凭什么能绕开这堵墙
算法·排序算法
tiger8657 小时前
大语言模型面试和题解,梳理中国主流开源 LLM 系列的发展脉络、技术路线与工程取舍
人工智能·gpt·深度学习·算法·自然语言处理·面试·transformer
我不会起名字3228 小时前
一天一道力扣Hot100(36):深度优先算法---组合总和
数据结构·c++·后端·python·算法·go
虚无的纽扣8 小时前
【力扣刷题】第三天:有效三角形的个数、快乐数
算法·排序算法
tiger8658 小时前
大语言模型面试和题解,Context Engineering 怎么做?长 Prompt、动态上下文与 Memory 管理
人工智能·深度学习·算法·语言模型·自然语言处理·面试·nlp