poj 3259 Wormholes ([kuangbin带你飞]专题四 最短路练习)
2016-11-01 11:28
363 查看
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
Sample Output
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.
题目大意:
农夫 FJ 有 N 块田地【编号 1...n】 (1<=N<=500)
田地间有 M 条路径 【双向】(1<= M <= 2500)
同时有 W 个孔洞,可以回到以前的一个时间点【单向】(1<= W <=200)
问:FJ 是否能在田地中遇到以前的自己
算法:flod算法
思路: 田地间的双向路径加边,权值为正
孔洞间的单向路径加边,权值为负【可以回到以前】
判断有向图是否存在负环
因为如果存在了负数环,时间就会不停的减少,
那么 FJ 就可以回到以前更远的地方,肯定能遇到以前的自己的
<pre name="code" class="html">#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn = 510;
const int inf = 9999999;
struct Node{
int u,v;
int t;
}E[2500*2+200+10];
int d[maxn];
int c;
int n,m,w;
bool flod(){
for(int i=1;i<maxn;i++) d[i]=inf;
d[1]=0; //到某个点的时间
for(int i=1;i<n;i++){
bool flag = false;
for(int j=0;j<c;j++){
int u=E[j].u;
int v=E[j].v;
int t=E[j].t;
if(d[v]>d[u]+t){ //g跟新每个点时间
d[v]=d[u]+t;
flag = true;
}
}
if(!flag) return false; //如果不能跟新则不存在负边
}
for(int i=0;i<c;i++){
if(d[E[i].v]>d[E[i].u]+E[i].t) return true;
}
return false;
}
int main(){
int f;
scanf("%d",&f);
while(f--){
scanf("%d%d%d",&n,&m,&w);
c=0;
for(int i=0;i<m;i++){ //m条双向正边
int u,v,t;
scanf("%d%d%d",&u,&v,&t);
E[c].u=u;
E[c].v=v;
E[c].t=t;
c++;
E[c].u=v;
E[c].v=u;
E[c].t=t;
c++;
}
for(int i=0;i<w;i++){ //w条单向负边
int u,v,t;
scanf("%d%d%d",&u,&v,&t);
E[c].u=u;
E[c].v=v;
E[c].t=-t;
c++;
}
if(flod()){
printf("YES\n");
}
else printf("NO\n");
}
return 0;
}
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.
题目大意:
农夫 FJ 有 N 块田地【编号 1...n】 (1<=N<=500)
田地间有 M 条路径 【双向】(1<= M <= 2500)
同时有 W 个孔洞,可以回到以前的一个时间点【单向】(1<= W <=200)
问:FJ 是否能在田地中遇到以前的自己
算法:flod算法
思路: 田地间的双向路径加边,权值为正
孔洞间的单向路径加边,权值为负【可以回到以前】
判断有向图是否存在负环
因为如果存在了负数环,时间就会不停的减少,
那么 FJ 就可以回到以前更远的地方,肯定能遇到以前的自己的
<pre name="code" class="html">#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn = 510;
const int inf = 9999999;
struct Node{
int u,v;
int t;
}E[2500*2+200+10];
int d[maxn];
int c;
int n,m,w;
bool flod(){
for(int i=1;i<maxn;i++) d[i]=inf;
d[1]=0; //到某个点的时间
for(int i=1;i<n;i++){
bool flag = false;
for(int j=0;j<c;j++){
int u=E[j].u;
int v=E[j].v;
int t=E[j].t;
if(d[v]>d[u]+t){ //g跟新每个点时间
d[v]=d[u]+t;
flag = true;
}
}
if(!flag) return false; //如果不能跟新则不存在负边
}
for(int i=0;i<c;i++){
if(d[E[i].v]>d[E[i].u]+E[i].t) return true;
}
return false;
}
int main(){
int f;
scanf("%d",&f);
while(f--){
scanf("%d%d%d",&n,&m,&w);
c=0;
for(int i=0;i<m;i++){ //m条双向正边
int u,v,t;
scanf("%d%d%d",&u,&v,&t);
E[c].u=u;
E[c].v=v;
E[c].t=t;
c++;
E[c].u=v;
E[c].v=u;
E[c].t=t;
c++;
}
for(int i=0;i<w;i++){ //w条单向负边
int u,v,t;
scanf("%d%d%d",&u,&v,&t);
E[c].u=u;
E[c].v=v;
E[c].t=-t;
c++;
}
if(flod()){
printf("YES\n");
}
else printf("NO\n");
}
return 0;
}
相关文章推荐
- poj 3660 Cow Contest ([kuangbin带你飞]专题四 最短路练习)
- poj 1502 MPI Maelstrom([kuangbin带你飞]专题四 最短路练习)
- poj 2240 Arbitrage ([kuangbin带你飞]专题四 最短路练习)
- [kuangbin带你飞]专题四 最短路练习 D POJ 3268
- poj 1860 Currency Exchange ([kuangbin带你飞]专题四 最短路练习)
- poj 3268 Silver Cow Party ([kuangbin带你飞]专题四 最短路练习)
- [kuangbin带你飞]专题四 最短路练习 M POJ 1062
- 【算法系列学习】SPFA邻接表最短路 [kuangbin带你飞]专题四 最短路练习 F - Wormholes
- POJ 3259 Wormholes(floyd求负环,最短路)
- poj 3259 Wormholes(最短路Bellman-Ford算法)
- POJ 3259 Wormholes(最短路)
- Wormholes( POJ 3259)(Bellman-Ford+SPFA)(判断是否有负权环)(最短路模板)
- Poj_3259 Wormholes(最短路)
- [kuangbin带你飞]专题四 最短路练习 G POJ 1502
- [POJ 3259] Wormholes 最短路判负环(SPFA版)
- [kuangbin带你飞]专题四 最短路练习 H POJ 3660
- POJ-3259 Wormholes( 最短路 )
- POJ 3259 Wormholes(最短路Bellman_Ford)
- POJ-3259 Wormholes(最短路,bellman求负环)
- POJ 3259 Wormholes (最短路 SPFA 判断负环)