• POJ3259 Wormholes


    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 44261   Accepted: 16285

    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.

    Source

    普通路是双向边!虫洞是单向边!所以边数组要开到M*2+W!

    一定要好好看题呀,不然WA了都不知道为啥,一定要算好数据范围啊,不然RE了都不知道为啥……

    至于问题本身,判图里有没有负环就行了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<queue>
     7 using namespace std;
     8 const int mxn=8000;
     9 struct edge{
    10     int v,dis;
    11     int next;
    12 }e[mxn];
    13 int hd[mxn],cnt;
    14 int n,m,w;
    15 void add_edge(int u,int v,int dis){
    16     e[++cnt].v=v;e[cnt].next=hd[u];e[cnt].dis=dis;hd[u]=cnt;
    17 }
    18 int inq[mxn],dis[mxn];
    19 int vis[mxn];
    20 bool SPFA(int s){
    21     memset(vis,0,sizeof vis);
    22     memset(dis,0x3f,sizeof dis);
    23     memset(inq,0,sizeof inq);
    24     queue<int>q;
    25     inq[s]=1;dis[s]=0;vis[s]=1;
    26     q.push(s);
    27     while(!q.empty()){
    28         int u=q.front();q.pop();
    29         for(int i=hd[u];i;i=e[i].next){
    30             int v=e[i].v;
    31             if(dis[u]+e[i].dis<dis[v]){
    32                 dis[v]=dis[u]+e[i].dis;
    33                 vis[v]++;
    34                 if(vis[v]>n){
    35                     printf("YES
    ");
    36                     return 0;
    37                 }
    38                 if(!inq[v]){
    39                     inq[v]=1;
    40                     q.push(v);
    41                 }
    42             }
    43         }
    44         inq[u]=0;
    45     }
    46     return 1;
    47 }
    48 int main(){
    49     int T;
    50     scanf("%d",&T);
    51     while(T--){
    52         memset(hd,0,sizeof hd);
    53         memset(e,0,sizeof e);
    54         cnt=0;
    55         scanf("%d%d%d",&n,&m,&w);
    56         int i,j;
    57         int x,y,d;
    58         for(i=1;i<=m;i++){
    59             scanf("%d%d%d",&x,&y,&d);
    60             add_edge(x,y,d);
    61             add_edge(y,x,d);
    62         }
    63         for(i=1;i<=w;i++){
    64             scanf("%d%d%d",&x,&y,&d);
    65             add_edge(x,y,-d);            
    66         }
    67         bool flag=0;
    68         for(i=1;i<=n;i++){
    69             if(!SPFA(i)){flag=1;break;}
    70         }
    71         if(!flag)printf("NO
    ");
    72     }
    73     return 0;
    74 }
  • 相关阅读:
    上市前为什么要分红
    在文件开始追加一行
    c++ 日期时间工具
    windows c++找不到time.h sys/types.h
    截取ls -l的某一列
    提取指定类型文件到指定目录,保留目录结构
    批量转换当前目录下的文件名为snake case
    vcpkg boost uuid Bcrypt 链接问题
    文件名pascal转underscore
    vcpkg cmake 找不到boost
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/5766720.html
Copyright © 2020-2023  润新知