POJ 3259 Wormholes (Bellman-Ford算法的运用)

题目类型  Bellman-Ford算法的运用

题目意思
给出 n (1 <= n <= 500) 个点, m (1 <= m <= 2500) 条双向边 和 w (1 <= w <= 200) 条单向边 其中双向边的边权为正 单向边边权为负
问能否从某个点出发最终回到这个点 经过的边的权值加起来是负的

解题方法
和poj1860相似 看是否存在负环即可

参考代码 - 有疑问的地方在下方留言 看到会尽快回复的
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 6000;
const int INF = 1<<29;

struct P {
	int u, v, t;
}E[maxn];
int d[maxn];

int main() {
	freopen("in", "r", stdin);
	int t;
	scanf("%d", &t);
	while(t--) {
		int n, m, w;
		int ne = 0;
		scanf("%d%d%d", &n, &m, &w);
		for( int i=0; i<m; i++ ) {
			int u, v, t;
			scanf("%d%d%d", &u, &v, &t);
			E[ne].u = u; E[ne].v = v; E[ne++].t = t;
			E[ne].u = v; E[ne].v = u; E[ne++].t = t;
		}
		for( int i=0; i<w; i++ ) {
			int u, v, t;
			scanf("%d%d%d", &u, &v, &t);
			E[ne].u = u; E[ne].v = v; E[ne++].t = -t;
		}
		for( int i=1; i<=n; i++ ) d[i] = INF;
		d[1] = 0;
		for( int i=0; i<n; i++ ) {
			bool flag = false;
			for( int j=0; j<ne; j++ ) {
				int u = E[j].u, v = E[j].v;
				if(d[v] > d[u] + E[j].t) {
					d[v] = d[u] + E[j].t;
					flag = true;
				}
			}
			if(i == n-1) { // 松弛n-1次后还可以松弛说明存在负环
				 if(flag) printf("YES\n");
				 else printf("NO\n");
			}
		}
	}
	return 0;
}


你可能感兴趣的:(图论,Bellman-Ford)