[ACM] POJ 3259 Wormholes (bellman-ford最短路径,推断是否存在负权回路)
2014-09-08 11:51
357 查看
Wormholes
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.
Source
USACO 2006 December Gold
解题思路:
这题什么意思读了半天也没弄懂。。在POJ上做题头一大难关就是读题意。。。
农民有N块地,每块地看做一个节点,有m条普通的路(双向),连接着两个节点,从一端走到还有一端须要w时间(权值),还有wh条特殊的单向路,也就是题意中的虫洞,虫洞也连接着两个节点,但虫洞是单向的,从起点走到终点须要w时间,但这个时间是负的,也就是题意中所说的时光倒流,比方 一个虫洞连接着s -> e,在s处如果时间为6,走虫洞时间为4,那么走过去时光倒流,走到e时时间就变为了2 (6 -4,也就是虫洞这条路的权值为 -4 ) ,好奇妙。。。。问有没有这样一种情况,就是第二次走到某个节点的时间比第一次走到该节点所用的时间短(题中的Perhaps
he will be able to meet himself,时光倒流的作用)。如果存在这样的情况,那么以某节点为起点和终点一定存在着一个回路,这个回路的权值是负的,这样第二次所用的时间一定比第一次少。
bellman-ford求最短路径算法中的第三步就是推断一个图(有向图,或无向图)中是否存在负权回路。
bellman-ford算法參考:http://blog.csdn.net/niushuai666/article/details/6791765
代码:
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 29971 | Accepted: 10844 |
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
解题思路:
这题什么意思读了半天也没弄懂。。在POJ上做题头一大难关就是读题意。。。
农民有N块地,每块地看做一个节点,有m条普通的路(双向),连接着两个节点,从一端走到还有一端须要w时间(权值),还有wh条特殊的单向路,也就是题意中的虫洞,虫洞也连接着两个节点,但虫洞是单向的,从起点走到终点须要w时间,但这个时间是负的,也就是题意中所说的时光倒流,比方 一个虫洞连接着s -> e,在s处如果时间为6,走虫洞时间为4,那么走过去时光倒流,走到e时时间就变为了2 (6 -4,也就是虫洞这条路的权值为 -4 ) ,好奇妙。。。。问有没有这样一种情况,就是第二次走到某个节点的时间比第一次走到该节点所用的时间短(题中的Perhaps
he will be able to meet himself,时光倒流的作用)。如果存在这样的情况,那么以某节点为起点和终点一定存在着一个回路,这个回路的权值是负的,这样第二次所用的时间一定比第一次少。
bellman-ford求最短路径算法中的第三步就是推断一个图(有向图,或无向图)中是否存在负权回路。
bellman-ford算法參考:http://blog.csdn.net/niushuai666/article/details/6791765
代码:
#include <iostream> #include <iostream> using namespace std; const int inf=10010; const int maxn=6000; struct Edge//边结构体 { int s,e,w; }edge[maxn]; int dis[maxn];//到达各顶点的距离 int nodeNum,edgeNum;//节点个数,边个数 bool bellman_ford() { for(int i=0;i<=nodeNum;i++) dis[i]=inf;//初始化 bool ok;//推断是否发生了松弛 for(int i=1;i<=nodeNum-1;i++) { ok=0; for(int j=1;j<=edgeNum;j++) { if(dis[edge[j].s]+edge[j].w<dis[edge[j].e]) { dis[edge[j].e]=dis[edge[j].s]+edge[j].w; ok=1; } } if(!ok)//没有发生松弛,及时退出 break; } for(int i=1;i<=edgeNum;i++)//寻找负权回路 if(dis[edge[i].s]+edge[i].w<dis[edge[i].e]) return true;//存在负权回路 return false; } int main() { int t;cin>>t; int n,m,wh; while(t--) { cin>>n>>m>>wh;//n为节点,m为双向边,wh为单向边 nodeNum=n; edgeNum=m*2+wh; int cnt=1; int s,e,w;//起点,终点,权值 for(int i=1;i<=m;i++) { cin>>s>>e>>w; edge[cnt].s=s; edge[cnt].e=e; edge[cnt++].w=w; edge[cnt].s=e; edge[cnt].e=s; edge[cnt++].w=w; } for(int i=1;i<=wh;i++) { cin>>s>>e>>w; edge[cnt].s=s; edge[cnt].e=e; edge[cnt++].w=-w;//注意是负权 } if(bellman_ford())//存在负权回路 cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }
相关文章推荐
- [ACM] POJ 3259 Wormholes (bellman-ford最短路径,判断是否存在负权回路)
- POJ 3259 Wormholes (Bellman-Ford/SPFA 判断是否存在负权环)
- POJ 3259 Wormholes (Bellman-Ford/SPFA 判断是否存在负权环)
- POJ 3259 Wormholes (Bellman-Ford/SPFA 判断是否存在负权环)
- POJ 3259 Wormholes (Bellman-Ford/SPFA 判断是否存在负权环)
- POJ 3259 Wormholes (Bellman-Ford/SPFA 判断是否存在负权环)
- POJ 3259 Wormholes (Bellman-Ford/SPFA 判断是否存在负权环)
- POJ 3259 Wormholes (Bellman-Ford/SPFA 判断是否存在负权环)
- POJ 1860 Currency Exchange Bellman-Ford算法求单源最短路径并判断是否有正权回路
- poj1860(Bellman-Ford变形,含负权的单源最短路径,判断是否有正权环)
- POJ 3259 Wormholes(Bellman-Ford判断是否有负权边)
- POJ-3259 Wormholes(负权回路[Bellman-Ford])
- poj 3259 bellman-ford算法 判断是否存在负权回路
- Wormholes( POJ 3259)(Bellman-Ford+SPFA)(判断是否有负权环)(最短路模板)
- POJ 3259 Wormholes(判断负权回路|SPFA||Bellman-Ford)
- POJ 3259 Wormholes(bellman_ford,判断有没有负环回路)
- PKU 3259 Wormholes - 判断负权回路 Bellman-Ford
- [ACM] hdu 1217 Arbitrage (bellman_ford最短路,推断是否有正权回路或Floyed)
- Bellman-Ford存在负权的最短路径C++实现
- POJ - 3259 Wormholes解题报告(Bellman-Ford判断有向图中是否有负权环)