Wormholes POJ - 3259 最短路之找负圈(Bellman-Ford)

传送门

题目大意: 约翰有N个农场, 农场之间有M条路 和 W 个虫洞, 其中路是双向的, 话费时间t, 而虫洞花费的时间是负的, 而且是单向的. 问, 约翰能不能从一个农场出发, 通过这些虫洞和路回到这个农场, 而且时间在这个时间之前.

题目分析: 很明显是找负圈的裸题, 农场做顶点, 路和虫洞做边建图, 其中虫洞的边权重是负的即可. 用Bellman-Ford算法找有没有负圈即可.

代码:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;
const int INF = 1e5;
const int MAXN = 505;
int d[MAXN];
int maxE;
struct edge
{
	int fo, to;
	int t;
}E[5550];

bool Bellman_Ford(int maxV)
{
	memset(d, 0, sizeof d);
	
	for(int i=0; i<maxV; ++i)
	{
		bool update = false;
		for(int j=0; j<maxE; ++j)
		{
			edge e = E[j];
			if(d[e.fo] + e.t < d[e.to])
			{
				update = true;
				d[e.to] = d[e.fo] + e.t;
			}
		}
		if(!update) break;
		if(i == maxV-1) return true;
	}
	return false;
}	


int main()
{
	int T, n, m, w;
	int s, e, t;
	cin >>T;
	while(T--)
	{
		scanf("%d%d%d", &n, &m, &w);
		for(int i=0; i<m; ++i)
		{
			scanf("%d%d%d", &s, &e, &t);
			E[i] = (edge){s, e, t};
			E[i+m] = (edge){e, s, t};
		}
		for(int i=0; i<w; ++i)
		{
			scanf("%d%d%d", &s, &e, &t);
			E[i+m*2] = (edge){s, e, -t};
		}
		maxE = m*2+w;
		if(Bellman_Ford(n)) printf("YES\n");
		else printf("NO\n");
	}

	return 0;
}

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