码迷,mamicode.com
首页 > 其他好文 > 详细

Bellman-Ford——解决负权边

时间:2014-12-04 23:15:21      阅读:283      评论:0      收藏:0      [点我收藏+]

标签:blog   http   io   ar   for   on   2014   问题   log   

Dijkstra算法虽好,但是不能解决带负权边的图,而Bellman-Ford就是解决这个问题的


在一个含有n个顶点的图中,任意两点之间的最短路径最多包含n-1条边,最短路径中不可能包含回路.

最短路径是一个不包含回路的简单路径,回路分为正权回路(回路权值之和为正)和负权回路(回路权值之和为负). 如果最短路径中包含正权回路,那么去掉这个回路,一定可以得到更短的路径;如果最短路径中包含负权回路,那么肯定没有最短路径,因为每多走一次负权回路就可以得到更短的路径. 因此最短路径肯定是一个不包含回路的最短路径,即最多包含n-1条边.

bubuko.com,布布扣

Code:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define INF 999999
int main(int argc, char const *argv[])
{
	int i, j, n, m;
	int dis[10], temp[10], u[10], v[10], w[10];
	int check, flag = 0;

	scanf("%d %d", &n, &m);
	for(i = 1; i <= m; ++i)
	{
		scanf("%d %d %d", &u[i], &v[i], &w[i]);
	}

	for(i = 1; i <= n; ++i)
	{
		dis[i] = INF;
	}
	dis[1] = 0;

///
	for(j = 1; j < n; ++j)     /// 最多循环n-1次
	{
		for(i = 1; i <= n; ++i)
		{
			temp[i] = dis[i];      /// 对BellmanFord优化,有可能在n-1轮松弛之前就已经计算出最短路径,所以先备份dis数组
		}

		for(i = 1; i <= m; ++i)        /// 最核心的3句Bellman-Ford算法
		{
			if(dis[v[i]] > dis[u[i]] + w[i])
			{
				dis[v[i]] = dis[u[i]] + w[i];
			}
		}

		check = 0;      /// 检测dis数组是否有更新
		for(i = 1; i <= n; ++i)
		{
			if(temp[i] != dis[i])
			{
				check = 1;
				break;
			}
		}

		if(!check)     ///  没有更新则提前退出程序
		{
			break;
		}
	}

	for(i = 1; i <= m; ++i)     /// n-1次之后最短路径还会发生变化则含有负权回路
	{
		if(dis[v[i]] > dis[u[i]] + w[i])
		{
			flag = 1;
		}
	}

	if(flag)
	{
		printf("负权回路");
	}
	else
	{
		for(i = 1; i <= n; ++i)
			{
				printf("%d ", dis[i]);
			}
	}
	printf("\n");

	system("pause");
	return 0;
}


Bellman-Ford——解决负权边

标签:blog   http   io   ar   for   on   2014   问题   log   

原文地址:http://blog.csdn.net/triumph92/article/details/41732385

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!