Wormholes
Time Limit: 2000MS | | Memory Limit: 65536K |
Total Submissions: 22876 | | Accepted: 8144 |
Description
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.
Source
//ac
// I'm the Topcoder
//C
#include
#include
#include
#include
#include
#include
//C++
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
//*************************OUTPUT*************************
#ifdef WIN32
#define INT64 "%I64d"
#define UINT64 "%I64u"
#else
#define INT64 "%lld"
#define UINT64 "%llu"
#endif
//**************************CONSTANT***********************
#define INF 0x3f3f3f3f
#define eps 1e-8
#define PI acos(-1.)
#define PI2 asin (1.);
typedef long long LL;
//typedef __int64 LL; //codeforces
typedef unsigned int ui;
typedef unsigned long long ui64;
#define MP make_pair
typedef vector VI;
typedef pair PII;
#define pb push_back
#define mp make_pair
//***************************SENTENCE************************
#define CL(a,b) memset (a, b, sizeof (a))
#define sqr(a,b) sqrt ((double)(a)*(a) + (double)(b)*(b))
#define sqr3(a,b,c) sqrt((double)(a)*(a) + (double)(b)*(b) + (double)(c)*(c))
//****************************FUNCTION************************
template double DIS(T va, T vb) { return sqr(va.x - vb.x, va.y - vb.y); }
template inline T INTEGER_LEN(T v) { int len = 1; while (v /= 10) ++len; return len; }
template inline T square(T va, T vb) { return va * va + vb * vb; }
// aply for the memory of the stack
//#pragma comment (linker, "/STACK:1024000000,1024000000")
//end
const int maxn = 1000000+100;
struct node{
int to;
int next;
long long weight;
};
node edge[maxn],edge1[maxn];//保存边的起点和终点
int n,m;
long long val;
int tot,tot1;
int src;//起点
int head[maxn],head1[maxn];
int visit[maxn],visit1[maxn];
long long dis[maxn],dis1[maxn];
long long ans[maxn],ans2[maxn];
long long MAXTIME=-INF;
int sum1[maxn],sum11[maxn];;
void add(int a,int b,long long c){
edge[tot].to=b;
edge[tot].weight=c;
edge[tot].next=head[a];
head[a]=tot++;
}
void add1(int a,int b,long long c){
edge1[tot1].to=b;
edge1[tot1].weight=c;
edge1[tot1].next=head1[a];
head1[a]=tot1++;
}
bool spfa(){
//初始化
for(int i=1;i<=n;i++){
dis[i]=INF;
visit[i]=0;//访问标记
sum1[i]=0;
}
dis[src]=0; visit[src]=1;
int u;
int v;
queue Q;//优先队列
Q.push(src);
while(!Q.empty()){
u=Q.front();
Q.pop();
visit[u]=0;
if(sum1[u]>n) return true;
for(int i=head[u];i!=-1;i=edge[i].next){
v=edge[i].to;
if(dis[v]>dis[u]+edge[i].weight){
dis[v]=dis[u]+edge[i].weight;
if(!visit[v]){
Q.push(v);
visit[v]=1;
sum1[v]++;
}
}
}
}
return false;
}
int main(){
int a,b,c,w;
int t;
scanf("%d",&t);
while( t--){
tot=tot1=0;//边的条数
scanf("%d%d%d",&n,&m,&w);//w个洞
for(int i=1;i<=n;i++){
head[i]=-1;
head1[i]=-1;
}
for(int i=1;i<=m;i++){
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
//add1(b,a,c);
}
for(int i=1;i<=w;i++){
scanf("%d%d%d",&a,&b,&c);
add(a,b,-c);
}
src=1;
if(spfa()){
printf("YES\n");
}
else printf("NO\n");
}
return 0;
}