poj 3259 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..NM (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, FF farm descriptions follow. 
Line 1 of each farm: Three space-separated integers respectively: NM, and W 
Lines 2..M+1 of each farm: Three space-separated numbers (SET) 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 (SET) 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
 
题目大意:虫洞问题,现在有n个点,m条边,代表现在可以走的通路,比如从a到b和从b到a需要花费c时间,现在在地上出现了w个虫洞,虫洞的意义就是你从a到花费的时间是-c(时间倒流,并且虫洞是单向的),现在问你从某个点开始走,能回到从前
本质就是求该图是否存在负环。也就是如何求出一个图是否含有负环。
注意:M是正权,双向,W是负权,单向
 
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 using namespace std;
 6 const int maxn=5300;
 7 const int INF=10001;
 8 struct node
 9 {
10     int s;
11     int e;
12     int t;
13 } path[maxn];
14 int n,m,w;
15 int val[maxn]; //源点到各点的权值
16 int index; //边的总数
17 void bellman()
18 {
19     memset(val,INF,sizeof(val));
20     bool flag;
21     for(int i=0; i<n-1; i++)
22     {
23         flag=false;
24         for(int j=0; j<index; j++)
25         {
26             if(val[path[j].e]>val[path[j].s]+path[j].t)
27             {
28                 val[path[j].e]=val[path[j].s]+path[j].t;
29                 flag=true;
30             }
31         }
32         if(!flag)
33             break;
34     }
35     for(int i=0; i<index; i++)
36     {
37         if(val[path[i].e]>val[path[i].s]+path[i].t)
38         {
39             cout<<"YES"<<endl;
40             return ;
41         }
42     }
43     cout<<"NO"<<endl;
44     return ;
45 }
46 int main()
47 {
48     int t;
49     int a,b,c;//临时变量
50     cin>>t;
51     while(t--)
52     {
53         index=0;
54         cin>>n>>m>>w;
55         for(int i=1; i<=m; i++) //正权边,双向
56         {
57             cin>>a>>b>>c;
58             path[index].s=a;
59             path[index].e=b;
60             path[index++].t=c;
61             path[index].s=b;
62             path[index].e=a;
63             path[index++].t=c;
64         }
65         for(int i=1; i<=w; i++) //负权边,单向
66         {
67             cin>>a>>b>>c;
68             path[index].s=a;
69             path[index].e=b;
70             path[index++].t=-c;
71         }
72         bellman();
73     }
74     return 0;
75 }
View Code

 这样也可以

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 using namespace std;
 6 const int maxn=5300;
 7 const int INF=10001;
 8 struct node
 9 {
10     int s;
11     int e;
12     int t;
13 } path[maxn];
14 int n,m,w;
15 int val[maxn]; //源点到各点的权值
16 int index; //边的总数
17 void bellman()
18 {
19     for(int i=1;i<=n;i++)
20         val[i]=INF;
21     val[1]=0;
22     bool flag;
23     for(int i=1; i<n; i++)
24     {
25         flag=false;
26         for(int j=1; j<index; j++)
27         {
28             if(val[path[j].e]>val[path[j].s]+path[j].t)
29             {
30                 val[path[j].e]=val[path[j].s]+path[j].t;
31                 flag=true;
32             }
33         }
34         if(!flag)
35             break;
36     }
37     if(flag)
38         cout<<"YES"<<endl;
39     else
40         cout<<"NO"<<endl;
41     return ;
42 }
43 int main()
44 {
45     int t;
46     int a,b,c;//临时变量
47     cin>>t;
48     while(t--)
49     {
50         index=1;
51         cin>>n>>m>>w;
52         for(int i=1; i<=m; i++) //正权边,双向
53         {
54             cin>>a>>b>>c;
55             path[index].s=a;
56             path[index].e=b;
57             path[index++].t=c;
58             path[index].s=b;
59             path[index].e=a;
60             path[index++].t=c;
61         }
62         for(int i=1; i<=w; i++) //负权边,单向
63         {
64             cin>>a>>b>>c;
65             path[index].s=a;
66             path[index].e=b;
67             path[index++].t=-c;
68         }
69         bellman();
70     }
71     return 0;
72 }
View Code
原文地址:https://www.cnblogs.com/cxbky/p/4907140.html