Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 36641 | Accepted: 13405 |
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
Hint
Source
题目链接:http://poj.org/problem?id=3259
题目大意:时空旅行,前m条路是双向的,旅行时间为正值,w条路是虫洞,单向的,旅行时间是负值,也就是能回到过去。求从一点出发,判断能否在”过去“回到出发点,即会到出发点的时间是负的。
解题思路:裸的负权最短路问题,SPAF解决。枚举出发点即可。
代码如下:
#include <cstdio> #include <cstring> #include <vector> #include <queue> #include <algorithm> #define inf 1e9 using namespace std; int const maxn=505; int n,p; int dist[maxn],vis[maxn],num[maxn]; struct node { int v,w; node(int vv,int ww) { v=vv; w=ww; } }; vector <node> vt[maxn]; void SPAF(int v0) { memset(vis,0,sizeof(vis)); memset(num,0,sizeof(num)); for(int i=0;i<maxn;i++) dist[i]=-inf; queue <int>q; q.push(v0); dist[v0]=0; while(!q.empty()) { int u=q.front(); q.pop(); if(num[u]>n) continue; num[u]++; if(num[u]>=n) dist[u]=inf; vis[u]=0; int len=vt[u].size(); for(int i=0;i<len;i++) { int v=vt[u][i].v; int w=vt[u][i].w; if(dist[v]<dist[u]+w) { dist[v]=dist[u]+w; if(v==v0&&dist[v]>0) { p=1; return ; } if(!vis[v]) { vis[v]=1; q.push(v); } } } } } int main(void) { int m1,m2,u,v,w,t; scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&m1,&m2); int ans=0; p=0; for(int i=0;i<maxn;i++) vt[i].clear(); for(int i=0;i<m1;i++) { scanf("%d%d%d",&u,&v,&w); //双向路径 vt[u].push_back(node(v,-w)); vt[v].push_back(node(u,-w)); } for(int i=0;i<m2;i++) { scanf("%d%d%d",&u,&v,&w); vt[u].push_back(node(v,w)); //单向路径 } for(int i=1;i<=n;i++) { SPAF(i); if(p) break; } if(p) printf("YES\n"); else printf("NO\n"); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
poj 3259 Wormholes (负权最短路,SPAF)
原文地址:http://blog.csdn.net/criminalcode/article/details/47687183