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 toF (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 题意:一个农村有N块田地 所有田地间有N条路径(双向), W个虫洞(负权,单向). 判断一个人能否 从起点1出发 经过某些路径 碰到以前的自己。 思路:SPFA 如果一个节点入队N次以上,则说明有负权回路 (等于N也不行,因为可能从起点到所有点都有通路 且权值依次递增,则起点会入队N次)。 入队N次 表示DIS[POS]一直在减少。 代码:#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; #define maxx 9999999 struct node { int to,w,pre; }edge[5555]; int next[555]; int dis[555]; int vis[555]; int num[555]; //某点的入队次数 int m,n1,n2,tot; void addedge() { int u,v,w; while(n1--) //双向 { scanf("%d%d%d",&u,&v,&w); edge[tot].w=w; edge[tot].to=v; edge[tot].pre=next[u]; next[u]=tot++; edge[tot].w=w; edge[tot].to=u; edge[tot].pre=next[v]; next[v]=tot++; } while(n2--) { scanf("%d%d%d",&u,&v,&w); edge[tot].w=-w; edge[tot].to=v; edge[tot].pre=next[u]; next[u]=tot++; } return; } int spfa() { int i,now; for(i=1;i<=m;i++) { dis[i]=maxx; num[i]=0; vis[i]=0; } vis[1]=1; dis[1]=0; queue<int>q; q.push(1); while(!q.empty()) { now=q.front(); q.pop(); vis[now]=0; num[now]++; if(num[now]>m) { return 1; } for(i=next[now];i!=-1;i=edge[i].pre) { if(dis[edge[i].to]>dis[now]+edge[i].w) { dis[edge[i].to]=dis[now]+edge[i].w; if(!vis[edge[i].to]) { vis[edge[i].to]=1; q.push(edge[i].to); } } } } return 0; } int main() { int t; int i,j; cin>>t; while(t--) { tot=1; memset(next,-1,sizeof(next)); scanf("%d%d%d",&m,&n1,&n2); addedge(); if(spfa()) printf("YES\n"); else printf("NO\n"); } return 0; }