zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    70. 爬楼梯
    278. 第一个错误的版本
    88. 合并两个有序数组
    C++string与int的相互转换(使用C++11)
    108. 将有序数组转换为二叉搜索树
    102. 二叉树的层次遍历
    101. 对称二叉树
    98. 验证二叉搜索树
    ServletContext对象
    ServletConfig对象
  • 原文地址:https://www.cnblogs.com/cxbky/p/4907140.html
Copyright © 2011-2022 走看看