您的位置:首页 > 其它

POJ 3259 Wormholes(SPFA判负权回路)

2016-09-08 19:47 363 查看
传送门:POJ 3259 Wormholes

描述:

Language:
Default

Wormholes

Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 44849 Accepted: 16528
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

USACO 2006 December Gold
题意:
John的农场里N块地,M条路连接两块地,W个虫洞;路是双向的,虫洞是一条单向路,会在你离开之前把你传送到目的地,

就是当你过去的时候时间会倒退Ts。我们的任务是知道会不会在从某块地出发后又回来,看到了离开之前的自己。

简言之,就是看图中有没有负权环。

思路:
判断每个点的入队次数,如果大于N(图中总的点数),就是有负环,SPFA随便搞一下,是个基础结论题

代码:

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;

//SPFA   实际上是BFS
const  int  inf=1e9;
const  int  maxn=555;
vector<pair<int,int> >E[maxn];//邻接表
int n,m;
int cnt[maxn];
int d[maxn],inq[maxn];

void  init(){
for(int i=0; i<maxn; i++)E[i].clear();
for(int i=0; i<maxn; i++)inq[i]=0;
for(int i=0; i<maxn; i++)d[i]=inf;
for(int i=0; i<maxn; i++)cnt[i]=0;
}

bool spfa(int n){
queue<int>q;
q.push(1),d[1]=0,inq[1]=1;
while(!q.empty()){
int now=q.front();
q.pop();inq[now]=0;
for(int i=0; i<E[now].size(); i++){
int  v=E[now][i].first;
if(d[v]>d[now]+E[now][i].second){
d[v]=d[now]+E[now][i].second;
if(inq[v]==1)continue;
inq[v]=1;
q.push(v);
if(++cnt[v]>n)return true;
}
}
}
return false;
}

int  main(){
int t;
scanf("%d",&t);
while(t--){
int n,m,W;
scanf("%d%d%d",&n,&m,&W);
init();
for(int i=0; i<m; i++){
int x,y,z;scanf("%d %d %d",&x,&y,&z);
E[x].push_back(make_pair(y,z));  //边x,y,边权z
E[y].push_back(make_pair(x,z));
}
for(int i=0; i<W; i++){
int x,y,z;scanf("%d %d %d",&x,&y,&z);
E[x].push_back(make_pair(y,-z));
}
if(spfa(n))printf("YES\n");
else printf("NO\n");
}
return  0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  最短路