题目描述
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.
John在他的农场中闲逛时发现了许多虫洞。虫洞可以看作一条十分奇特的有向边,并可以使你返回到过去的一个时刻(相对你进入虫洞之前)。John的每个农场有M条小路(无向边)连接着N (从1..N标号)块地,并有W个虫洞。其中1<=N<=500,1<=M<=2500,1<=W<=200。 现在John想借助这些虫洞来回到过去(出发时刻之前),请你告诉他能办到吗。 John将向你提供F(1<=F<=5)个农场的地图。没有小路会耗费你超过10000秒的时间,当然也没有虫洞回帮你回到超过10000秒以前。
【题目分析】
判负环。
【代码】
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int fr[100001],to[100001],w[100001],dis[100001];
int n,m,mm,en;
inline bool BF()
{
memset(dis,0x3f,sizeof dis);
dis[1]=0;
for (int k=1;k<=m+mm;++k)
for (int i=1;i<=en;++i)
dis[to[i]]=min(dis[to[i]],dis[fr[i]]+w[i]);
// for (int i=1;i<=n;++i) cout<<dis[i]<<" ";
// cout<<endl;
for (int i=1;i<=en;++i)
if (dis[to[i]]>dis[fr[i]]+w[i]) return true;
return false;
}
int main()
{
int tt;
scanf("%d",&tt);
while (tt--)
{
en=0;
scanf("%d%d%d",&n,&m,&mm);
for (int i=1;i<=m;++i)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
fr[++en]=a;to[en]=b;w[en]=c;
fr[++en]=b;to[en]=a;w[en]=c;
}
for (int i=1;i<=mm;++i)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
fr[++en]=a;to[en]=b;w[en]=-c;
}
if (BF()) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}