Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 37415 | Accepted: 13764 |
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 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
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#include<stdio.h> #include<string.h> #include<queue> #include<algorithm> using namespace std; #define INF 0x3f3f3f int m,n,cnt,p; int head[1010],vis[1010],used[1010],dist[1010]; struct node { int u,v; int val,next; }edge[20010]; void add(int u,int v,int val) { edge[cnt].u=u; edge[cnt].v=v; edge[cnt].val=val; edge[cnt].next=head[u]; head[u]=cnt++; } int SPFA(int st) { queue<int>q; memset(dist,INF,sizeof(dist)); memset(used,0,sizeof(used)); memset(vis,0,sizeof(vis)); vis[st]=1; dist[st]=0; q.push(st);//各种初始化 while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0;//进入循环一定要改成0,这样才能判断进入了多少次 for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(dist[v]>dist[u]+edge[i].val) { dist[v]=dist[u]+edge[i].val; if(!vis[v]) { vis[v]=1; used[v]++; if(used[v]>=m)//判断是否出现了负权边 return 1; q.push(v); } } } } return 0; } int main() { int t; scanf("%d",&t); while(t--) { memset(head,-1,sizeof(head)); scanf("%d%d%d",&m,&n,&p); int x,y,z; while(n--) { scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z); } while(p--) { scanf("%d%d%d",&x,&y,&z); add(x,y,-z); add(y,x,INF);//虫洞是单向的,所以反向是无穷 } if(SPFA(1)) printf("YES "); else printf("NO "); } return 0; }