最短路 Bellman-ford算法

最短路 Bellman-ford算法

  • 可以用来解决带负值的最短路,并且可以用来判断负环
  • 时间复杂度o(m*n) (m是边数,n是点数)
  • 具体步骤:
    用 u[] v[] w[]来存一条边 松弛的时候每次用 u[i]-v[i]这条边来松弛 初始点到 v[i]这条边。核心代码如下:
	for(int i=1;i<=n-1;i++)///松弛次数 
	{
		for(int j=1;j<=m;j++)///每条边松弛 
		{
			if(dis[v[j]]>dis[u[j]]+w[j])
				dis[v[j]]=dis[u[j]]+w[j];
		}
	}

至于为什么要松弛 n-1次呢 ?松弛k 次就是 a-b之间最多通过k个点来相连,然而一个n个顶点的最短路径最多就n-1 条边,所以n-1次以后一定能够找到最短路。完整代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define inf 0x3f3f3f3f 
using namespace std;
int u[1010];
int v[1010];
int w[1010];
int n,m;
int dis[1010];
int main()
{
	cin>>m>>n;
	for(int i=1;i<=n;i++)
		dis[i]=inf;
	for(int i=1;i<=m;i++)
		cin>>u[i]>>v[i]>>w[i];

	dis[1]=0;
	for(int i=1;i<=n-1;i++)///松弛次数 
	{
		for(int j=1;j<=m;j++)///每条边松弛 
		{
			if(dis[v[j]]>dis[u[j]]+w[j])
				dis[v[j]]=dis[u[j]]+w[j];
		}
	}
	for(int i=1;i<=n;i++)
		cout<<dis[i]<<endl; 
}
/*5 5 2 3 2 1 2 -3 1 5 5 4 5 2 3 4 3*/

0
-3
-1
2
4
  • 检测负环(负权回路)只要再加几行语句就行,就是让他在松弛一次,看看dis[]数组是还能改变,能改变就说明有负权回路,反之则没有
	int flag=0;
	for(int i=1;i<=m;i++)
		if(dis[v[j]]>dis[u[j]]+w[j])
			flag=1;
	if(flag==1)
		cout<<"有负权回路"<<endl; 
    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/weixin_43179892/article/details/83450539
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞