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
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<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<map> #include<queue> using namespace std; const int INF=0x3f3f3f3f; const int MAXN=500+5; const int MAXM=5700+5; int u[MAXM]; int v[MAXM]; int w[MAXM]; int d[MAXN]; int MIN(int x,int y){return x>y?y:x;} int MAX(int x,int y){return x<y?y:x;} bool bellman(int n,int m,int t) { int i,j,k; for(i=1;i<=n;i++)d[i]=INF; d[t]=0; for(i=1;i<n;i++) for(j=1;j<=m;j++) if(d[u[j]]+w[j]<d[v[j]])d[v[j]]=d[u[j]]+w[j]; for(j=1;j<=m;j++) if(d[u[j]]+w[j]<d[v[j]])return 1; return 0; } int main() { //freopen("123.txt","r",stdin); int N,n,m,c; while(~scanf("%d",&N)) { int e,i; while(N--) { scanf("%d%d%d",&n,&m,&c); for(e=1;e<=m+c;e++) { scanf("%d%d%d",&u[e],&v[e],&w[e]); if(e>m)w[e]*=-1; } for(e=m+c+1;e<=2*m+c;e++) { u[e]=v[e-m-c]; v[e]=u[e-m-c]; w[e]=w[e-m-c]; } if(bellman(n,2*m+c,1))printf("YES\n"); else printf("NO\n"); } } return 0; }优化版本:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<map> #include<queue> using namespace std; const int INF=0x3f3f3f3f; const int MAXN=500+5; const int MAXM=5700+5; int u[MAXM]; int v[MAXM]; int w[MAXM]; int d[MAXN]; int MIN(int x,int y){return x>y?y:x;} int MAX(int x,int y){return x<y?y:x;} bool bellman(int n,int m,int t) { int i,j,k; for(i=1;i<=n;i++)d[i]=INF; d[t]=0; for(i=1;i<=n;i++) { int flag=1; for(j=1;j<=m;j++) if(d[u[j]]+w[j]<d[v[j]]) { d[v[j]]=d[u[j]]+w[j]; flag=0; } if(flag)break; } if(i==n+1)return 1; return 0; } int main() { //freopen("123.txt","r",stdin); int N,n,m,c; while(~scanf("%d",&N)) { int e,i; while(N--) { scanf("%d%d%d",&n,&m,&c); for(e=1;e<=m+c;e++) { scanf("%d%d%d",&u[e],&v[e],&w[e]); if(e>m)w[e]*=-1; } for(e=m+c+1;e<=2*m+c;e++) { u[e]=v[e-m-c]; v[e]=u[e-m-c]; w[e]=w[e-m-c]; } if(bellman(n,2*m+c,1))printf("YES\n"); else printf("NO\n"); } } return 0; }
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<map> #include<queue> using namespace std; const int INF=0x3f3f3f3f; const int MAXN=500+5; const int MAXM=5700+5; int u[MAXM]; int v[MAXM]; int w[MAXM]; int first[MAXN]; int next[MAXM]; int d[MAXN]; bool inq[MAXN]; int num[MAXN]; int MIN(int x,int y){return x>y?y:x;} int MAX(int x,int y){return x<y?y:x;} int cnt; void add_dedge(int u,int v,int w,int i) { next[i]=first[u]; first[u]=i; cnt++; } bool bellman(int n,int m,int t) { int i; queue<int>q; memset(inq,0,sizeof inq); memset(num,0,sizeof num); for(i=1;i<=n;i++)d[i]=INF; d[t]=0; q.push(t); num[t]++; //inq[t]=1; while(!q.empty()) { int e,x=q.front();q.pop(); inq[x]=0; for(e=first[x];e!=-1;e=next[e]) { if(d[x]+w[e]<d[v[e]]) { d[v[e]]=d[x]+w[e]; if(!inq[v[e]]) { q.push(v[e]); num[v[e]]++; if(num[v[e]]>=n)return 1; inq[v[e]]=1; } } } } return 0; } int main() { //freopen("123.txt","r",stdin); int N,n,m,c; while(~scanf("%d",&N)) { int e,i; while(N--) { cnt=1; memset(first,-1,sizeof first); memset(next,-1,sizeof next); scanf("%d%d%d",&n,&m,&c); while(m--) { scanf("%d%d%d",&u[cnt],&v[cnt],&w[cnt]); add_dedge(u[cnt],v[cnt],w[cnt],cnt); u[cnt]=v[cnt-1]; v[cnt]=u[cnt-1]; w[cnt]=w[cnt-1]; add_dedge(u[cnt],v[cnt],w[cnt],cnt); } while(c--) { scanf("%d%d%d",&u[cnt],&v[cnt],&w[cnt]); w[cnt]*=-1; add_dedge(u[cnt],v[cnt],w[cnt],cnt); } cnt--; if(bellman(n,cnt,1))printf("YES\n"); else printf("NO\n"); } } return 0; }