POJ - 3259 Wormholes ~~spfa判断是否有负环

Wormholes

 

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 path that delivers you to its destination at a time that is BEFORE you entered the wormhole! Each of FJ's farms comprises N (1 ≤ N ≤ 500) fields conveniently numbered 1..NM (1 ≤ M≤ 2500) paths, and W (1 ≤ W ≤ 200) wormholes.

As FJ is an avid time-traveling fan, he wants to do the following: start at some field, travel through some paths and wormholes, and return to the starting field a time before his initial departure. Perhaps he will be able to meet himself :) .

To help FJ find out whether this is possible or not, he will supply you with complete maps to F (1 ≤ F ≤ 5) of his farms. No paths will take longer than 10,000 seconds to travel and no wormhole can bring FJ back in time by more than 10,000 seconds.

Input
Line 1: A single integer,  FF farm descriptions follow. 
Line 1 of each farm: Three space-separated integers respectively:  NM, and  W 
Lines 2..  M+1 of each farm: Three space-separated numbers (  SET) that describe, respectively: a bidirectional path between  S and  E that requires  T seconds to traverse. Two fields might be connected by more than one path. 
Lines  M+2..  MW+1 of each farm: Three space-separated numbers (  SET) that describe, respectively: A one way path from  S to  E that also moves the traveler back T seconds.
Output
Lines 1..  F: For each farm, output "YES" if FJ can achieve his goal, otherwise output "NO" (do not include the quotes).
Sample Input
2
3 3 1
1 2 2
1 3 4
2 3 1
3 1 3
3 2 1
1 2 3
2 3 4
3 1 8
Sample Output
NO
YES
Hint
For farm 1, FJ cannot travel back in time. 
For farm 2, FJ could travel back in time by the cycle 1->2->3->1, arriving back at his starting location 1 second before he leaves. He could start from anywhere on the cycle to accomplish this.

          就是让你看下~~主角是否能够通过穿越单向的虫洞(权值为负)来达到不断返回过去的情况~~建成图之后就是判定是否存在负环的存在问题~~

#include<cstdio>
#include<queue>
#include<iostream>
using namespace std;
int m, n;
int head[1000];//链式前向星
struct edge
{
	int to;
	int ne ;
	int len;
}ed[10000];//储存边~~
int time[1000];//用来判断是否有负环
bool vis[1000];
int d[1000];//距离(在这里代表时间)
int cnt = 0;
void init()//初始化
{
	for (int s = 0; s <= 999; s++)
	{
		head[s] = -1;
	}
	for (int s = 0; s <= n; s++)
	{
		d[s] = 999999;
	}
	for (int s = 0; s < 9000; s++)
	{
		ed[s].ne = -1;
	}
	memset(vis, 0, sizeof(vis));
	memset(time, 0, sizeof(time));
}
void add(int from, int to, int len)
{
	ed[cnt].to = to;
	ed[cnt].len = len;
	ed[cnt].ne = head[from];
	head[from] = cnt++;
}
bool spfa()//返回是否能有负环
{
	d[1] = 0;
	queue<int>q;
	q.push(1);
	vis[1] = 1;
	bool flag = false;
	while (!q.empty())
	{
		int t = q.front();
		q.pop();
	//	cout << t << endl;
	//	cout << head[t] << endl;
		for (int s = head[t]; ~s; s = ed[s].ne)
		{
		//	cout << t << " " << ed[s].to << endl;
			if (d[ed[s].to] > d[t] + ed[s].len)
			{
				d[ed[s].to] = d[t] + ed[s].len;
				if (!vis[ed[s].to])
				{
			//		cout << ed[s].to << endl;
					vis[ed[s].to] = 1;
					time[ed[s].to]++;
					if (time[ed[s].to] > n)
					{
						flag = true;
						return flag;
					}
					q.push(ed[s].to);
				}
			}
		}
		vis[t] = 0;
	}
	return flag;
}
int main()
{
	int w, te;
	scanf("%d", &te);
	while (te--)
	{
		cin >> n >> m >> w;
		cnt = 0;
		init();
		for (int s = 0; s < m; s++)
		{
			int a, b, c;
			cin >> a >> b >> c;
			add(a, b, c);//开始的时候是双向边
			add(b, a, c);
		}
		for (int s = 0; s < w; s++)
		{
			int a, b, c;
			scanf("%d%d%d", &a, &b, &c);
			add(a, b, -c);//虫洞~~负边
		}
	//	cout << " " << d[3] << endl;
		bool ans = spfa();
		if (ans)
		{
			cout << "YES" << endl;
		}
		else
		{
			cout << "NO" << endl;
		}
		while (1)
		{
			break;
		}
	//	cout << d[n] << endl;
	}
	return 0;
}


 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值