POJ3259 Wormholes-Bellman-Ford算法

题目链接 点击打开链接

判断是否有负权回路,bf模板,对所有点进行n-1次松弛操作,如果不存在负权回路,就找找出了所有点到起点的最短路,否则还能继续松弛。

松弛操作:如果一个点p到起点start的距离大于从起点到另一个点other,再到p的距离,就把start->p的距离修改为start->other->p的距离,这个叫松弛。

#include <cstdio>
#include <iostream>
#include <cstring>
#define INF 0xfffffff
using namespace std;
int n,m,w;
int G[505][505];            //图
struct Edge{            //边起点终点和权重
	int start,end;
	int weight;
}edge[3000];
int dis[505];                //起点1到i的距离

int num = 0;
void BellmanFord(){
	for(int i = 2;i <= n;i++)
		dis[i] = G[1][i];                //初始化
	dis[1] = 0;                //到自身距离为0
	//n-1次松弛操作		
	for(int i = 1;i < n;i++)
		for(int j = 0;j < num;j++){
			if(dis[edge[j].end] > dis[edge[j].start] + edge[j].weight)
				dis[edge[j].end] = dis[edge[j].start] + edge[j].weight;        //松弛
		}    
	bool flag = false;            //判断是否还能继续松弛
	for(int j = 0;j < num;j++){
		if(dis[edge[j].end] > dis[edge[j].start] + edge[j].weight){
			flag = true;
			break;
		}				
		}	
	if(flag){                //还能松弛说明有负权回路
		printf("YES\n");
	}else{
		printf("NO\n");
	}	
	
}

int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		scanf("%d%d%d",&n,&m,&w);
		int a,b,c;
		for(int i = 1;i <= n;i++)
			for(int j = 1;j <= n;j++)
				G[i][j] = INF;
		for(int i = 1;i <= n;i++)
			G[i][i] = 0;
		for(int i = 0;i < m;i++){
			scanf("%d%d%d",&a,&b,&c);
			G[a][b] = G[b][a] = min(G[a][b],c);			
		}
		for(int i = 0;i < w;i++){
			scanf("%d%d%d",&a,&b,&c);
			G[a][b] = -c;			
		}
		
		num = 0;
		
		for(int i = 1;i <= n;i++)
			for(int j = 1;j <= n;j++){
				if(i == j || G[i][j] == INF)
					continue;
				edge[num].start = i;
				edge[num].end = j;
				edge[num].weight = G[i][j];
				num++;
			}
		
		BellmanFord();
	}
		
	return 0;
}

    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/lmhlmh_/article/details/80555384
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞