POJ 3259

这几天转去尝试做leetcode,意外发现其实leetcode题做做还是挺有收获的,不过感觉OJ做起来收获更大些,这两个还是结合起来做好点。

这道题思路还是比较清晰的,利用bellman ford的思路,不过因为图可能不连通,所以参考kuangbin大佬的思路加了一个“超级源”(因为此题只需要判断负环即可,所以这种转化对于问题求解是等价的)

#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <string>
#include <stack>
#include <map>
#include <set>
using namespace std;

const int maxn= 505;

struct Edge{
	int s, e, t;
};
vector<Edge> edges;
int d[maxn];
int n, m, w;

void AddEdge(int s, int e, int t)
{
	edges.push_back((Edge){s, e, t});
}
int Bellman(int s)
{
	memset(d, 0x3f, sizeof(d));
	d[s]= 0;

	for (int i= 1; i< n; ++i){
		int flag= 1;
		for (vector<Edge>::iterator eIter= edges.begin(); edges.end()!= eIter; ++eIter){
			int u= eIter->s, v= eIter->e, t= eIter->t;
			if (d[v]> d[u]+t){
				flag= 0;
				d[v]= d[u]+t;
			}
		}
		if (flag){
			return true;
		}
	}

	for (vector<Edge>::iterator eIter= edges.begin(); edges.end()!= eIter; ++eIter){
		int u= eIter->s, v= eIter->e, t= eIter->t;
		if (d[v]> d[u]+t){
			return false;
		}
	}

	return true;
}
int main(int argc, char const *argv[])
{
	int F;
	scanf("%d", &F);

	while (F--){
		int s, e, t;
		scanf("%d %d %d", &n, &m, &w);
		edges.clear();
		for (int i= 1; i<= n; ++i){
			AddEdge(0, i, 0);
		}
		for (int i= 0; i< m; ++i){
			scanf("%d %d %d", &s, &e, &t);
			AddEdge(s, e, t);
			AddEdge(e, s, t);
		}
		for (int i= 0; i< w; ++i){
			scanf("%d %d %d", &s, &e, &t);
			AddEdge(s, e, -t);
		}
		Bellman(0) ? puts("NO") : puts("YES");
	}
	return 0;
}
posted @ 2021-04-08 22:07  IdiotNe  阅读(32)  评论(0编辑  收藏  举报