Bellman-Ford——解决负权边

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

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

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

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;
}
时间: 2024-08-11 07:49:33

Bellman-Ford——解决负权边的相关文章

Bellman-Ford(可解决负权边)--时间复杂度优化

Bellman-Ford 可解决带有负权边的最短路问题 解决负权边和Dijkstra相比是一个优点,Bellman-Ford的核心代码只有4行:: u[],v[],w[] 分别存一条边的顶点.权值,dis[]存从 1 源点到各个顶点的距离 for(i=1;i<=n-1;i++) for(j=1;j<=m;j++) if(dis[v[i]] > dis[u[i]]+w[i]) dis[v[i]] = dis[u[i]]+w[i]; 愿过程: 循环n-1次,把每个顶点每条边都松弛: 优化方法

python数据结构与算法——图的最短路径(Bellman-Ford算法)解决负权边

1 # Bellman-Ford核心算法 2 # 对于一个包含n个顶点,m条边的图, 计算源点到任意点的最短距离 3 # 循环n-1轮,每轮对m条边进行一次松弛操作 4 5 # 定理: 6 # 在一个含有n个顶点的图中,任意两点之间的最短路径最多包含n-1条边 7 # 最短路径肯定是一个不包含回路的简单路径(回路包括正权回路与负权回路) 8 # 1. 如果最短路径中包含正权回路,则去掉这个回路,一定可以得到更短的路径 9 # 2. 如果最短路径中包含负权回路,则每多走一次这个回路,路径更短,则不

poj3259 bellman——ford Wormholes解绝负权问题

Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 35103   Accepted: 12805 Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way p

Bellman - Ford 算法解决最短路径问题

Bellman - Ford 算法: 一:基本算法 对于单源最短路径问题,上一篇文章中介绍了 Dijkstra 算法,但是由于 Dijkstra 算法局限于解决非负权的最短路径问题,对于带负权的图就力不从心了,而Bellman - Ford算法可以解决这种问题. Bellman - Ford 算法可以处理路径权值为负数时的单源最短路径问题.设想可以从图中找到一个环路且这个环路中所有路径的权值之和为负.那么通过这个环路,环路中任意两点的最短路径就可以无穷小下去.如果不处理这个负环路,程序就会永远运

poj 3259 bellman最短路判断有无负权回路

Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 36717   Accepted: 13438 Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way p

Bellman—Ford算法思想

---恢复内容开始--- Bellman—Ford算法能在更普遍的情况下(存在负权边)解决单源点最短路径问题.对于给定的带权(有向或无向)图G=(V,E),其源点为s,加权函数w是边集E的映射.对图G运行Bellman—Ford算法的结果是一个布尔值,表明图中是否存在着一个从源点s可达的负权回路.若存在负权回路,单源点最短路径问题无解:若不存在这样的回路,算法将给出从源点s到图G的任意顶点v的最短路径值d[v] Bellman—Ford算法流程 分为三个阶段: (1)初始化:将除源点外的所有顶点

POJ 1860 Currency Exchange (Bellman ford)

Currency Exchange Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 22405   Accepted: 8095 Description Several currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and pe

poj 3259 Wormholes (负权最短路,SPAF)

Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 36641   Accepted: 13405 Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way p

UVa 515 - King (差分约束系统 + SPFA求带负权最短路)

下面是差分约束系统的详细介绍,以及解决方法~ 摘抄自 xuezhongfenfei(他好像也是转的....) 差分约束系统 X1 - X2 <= 0 X1 - X5 <= -1 X2 - X5 <= 1 X3 - X1 <= 5 X4 - X1 <= 4 X4 - X3 <= -1 X5 - X3 <= -3 X5 - X4 <= -3 不等式组(1) 全都是两个未知数的差小于等于某个常数(大于等于也可以,因为左右乘以-1就可以化成小于等于).这样的不等式组