Bellman-Ford算法

为了能够求解 含负权边的带权有向图 的单源最短路径问题, Bellman( 贝尔曼 ) Ford( 福特 ) 提出了 从源点逐次绕过其他顶点,以缩短到达终点的最短路径长度 的方法。
不能处理带负权边的无向图。图中不能包含权值总和为负值回路(负权值回路)

递推公式(求顶点u到源点v的最短路径)

dist 1 [u] = Edge[v][u]

dist k [u] =min{ distk-1 [u], min{ distk-1 [j] + Edge[j][u] } },j=0,1,…,n-1,j≠u

#define MAX_VER_NUM 10	//顶点个数最大值
#define MAX 1000000
int Edge[MAX_VER_NUM][MAX_VER_NUM];	//图的邻接矩阵
int vexnum;	//顶点个数
int path[MAX_VER_NUM]; //path[i]是源到i的最短路径中的i的前面那个点
void BellmanFord(int v) //假定图的邻接矩阵和顶点个数已经读进来了
{
	int i, k, u;
	for(i=0; i<vexnum; i++)
	{
		dist[i]=Edge[v][i];	//对dist[ ]初始化
		if( i!=v && dist[i]<MAX ) path[i] = v;	//对path[ ]初始化
		else path[i] = -1;
	}
<pre name="code" class="cpp">        for(k=2; k<vexnum; k++) //从dist1[u]递推出dist2[u], …,distn-1[u]
	{
		for(u=0; u< vexnum; u++)//修改每个顶点的dist[u]和path[u]
		{
			if( u != v )
			{
				for(i=0; i<vexnum; i++)//考虑其他每个顶点
				{
					if( Edge[i][u]<MAX &&
					    dist[u]>dist[i]+Edge[i][u] )
					{
						dist[u]=dist[i]+Edge[i][u];
						path[u]=i;
					}
				}
			}
		}
	}
}
 
 
 如果存在从源点可达的 
 负权值回路 
 ,则最短路径不存在,因为可以重复走这个回路,使得路径无穷小。
Bellman 算法中判断是否存在从源点可达的负权值回路的方法:

在求出distn-1[ ]之后,再对每条边<u,k>判断一下:加入这条边是否会使得顶点k最短路径值再缩短,即判断:

dist[u]+w(u,k)<dist[k]

是否成立,如果成立,则说明存在从源点可达的负权值回路

for (i=0;i<n;i++)
{
	for (j=0;j<n;j++)
	{
		if (Edge[i][j]<MAX && dist[j]>dist[i]+Edge[i][j])
			return 0;//存在从源点可达的负权值回路
	}
}
return 1;

如果成立,则说明找到了一条经过了n条边的从 sk路径,且其比任何少于n条边的从sk路径都短。

一共n个顶点,路径却经过了n条边,则必有一个顶点m经过了至少两次。m一个回路的起点和终点。

走这个回路比不走这个回路路径更短,只能说明这个回路是负权回路。






















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值