POJ 3259 Wormholes (Bellman-Ford算法判断负权回路)

F - 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…N, M (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, F. F farm descriptions follow.
Line 1 of each farm: Three space-separated integers respectively: N, M, and W
Lines 2… M+1 of each farm: Three space-separated numbers ( S, E, T) 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… M+ W+1 of each farm: Three space-separated numbers ( S, E, T) 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.

题意描述:
有n个农场和m条路,给出从一个农场到另一农场消耗的时间,并且有的农场里有虫洞,可以直接从一个农场到另一个农场,而且将倒回一些时间,现有一个人从一个农场出发,问他在回到出发地时能否看到出发前的自己。

解题思路:
利用Bellman-Ford算法判断有无负权回路。注意,农场之间的道路是双向的,虫洞是单向的。

AC代码:

#include<stdio.h>
#include<string.h>
int main(void)
{
	int i,j,k,w[10000],x[10000],y[10000],dis[10000]; 
	int  t,n,m,v,inf=9999999,z;
	scanf("%d",&t);
	while(t--)
	{
		memset(dis,0,sizeof(dis));
		scanf("%d%d%d",&n,&m,&v);
		k=m+v;
		for(i=1;i<=m;i++)
		{
			scanf("%d%d%d",&x[i],&y[i],&w[i]);
			x[++k]=y[i];//路径是双向的
			y[k]=x[i];
			w[k]=w[i]; 
			
		}
		for(j=m+1;j<=m+v;j++)
		{
			scanf("%d%d%d",&x[j],&y[j],&w[j]);
			w[j]=-w[j];
		}
		z=k;
		
		for(i=1;i<=n;i++)//初始化dis数组,dis数组用来存1号顶点到各个顶点的距离
		dis[i]=inf;
		dis[1]=0;
		for(i=1;i<=n;i++)//对所有边进行松弛
		{
			k=0;
			for(j=1;j<=z;j++)
			{
				if(dis[x[j]]>dis[y[j]]+w[j])
				{
					dis[x[j]]=dis[y[j]]+w[j];
					k=1;
				}
			}
			if(k==0)
			break;
		}
		k=0;
		for(i=1;i<=z;i++)//判断是否还能被松弛
		{
			if(dis[x[i]]>dis[y[i]]+w[i])
			{
				k=1;
				break;
			}
		}
		if(k==1)//还能松弛,存在负权回路
		printf("YES\n");
		else
		printf("NO\n");
	}
	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值