zoukankan      html  css  js  c++  java
  • poj 3259 Wormholes

    Wormholes
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 52062   Accepted: 19373

    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

    /*
    * @Author: Lyucheng
    * @Date:   2017-07-22 10:08:50
    * @Last Modified by:   Lyucheng
    * @Last Modified time: 2017-07-22 11:28:48
    */
    /*
     题意:给你一个图,无向边,其中有一条负边,问你有没有可能从一点出发,然后回到一点(看到原来的自己)
    
     思路:建图判断一下是不是有负环
    */
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define MAXN 505
    #define MAXM 3005
    #define INF 0x3f3f3f3f
    using namespace std;
    
    struct Edge  
    {  
        int from,to,dist;  
        Edge(int f,int t,int d):from(f),to(t),dist(d){}  
    };  
      
    struct BellmanFord  
    {  
        int n,m;            //点数和边数,编号都从0开始  
        vector<Edge> edges; //边列表  
        vector<int> G[MAXN];//每个节点出发的边编号(从0开始编号)  
        bool inq[MAXN];     //是否在队列中  
        int d[MAXN];        //s到各个点的距离  
        int p[MAXN];        //最短路中的上一条弧  
        int cnt[MAXN];      //进队次数  
      
        void init(int n)  
        {  
            this->n=n;  
            for(int i=0;i<n;i++) G[i].clear();  
            edges.clear();  
        }  
      
        void AddEdge(int from,int to,int dist)  
        {  
            edges.push_back(Edge(from,to,dist));  
            m = edges.size();  
            G[from].push_back(m-1);  
        }  
      
        //计算以s为源点的最短路径  
        //如果图中存在s能到达的负圈,那么返回true  
        bool negativeCycle(int s)
        {  
            queue<int> Q;  
            memset(inq,0,sizeof(inq));  
            memset(cnt,0,sizeof(cnt));  
            for(int i=0;i<n;i++) d[i]= i==s?0:INF;  
            Q.push(s);  
      
            while(!Q.empty())  
            {  
                int u=Q.front(); Q.pop();  
                inq[u]=false;  
                for(int i=0;i<G[u].size();i++)  
                {  
                    Edge &e=edges[G[u][i]];  
                    if(d[e.to] > d[u]+e.dist)  
                    {  
                        d[e.to] = d[u]+e.dist;  
                        p[e.to] = G[u][i];  
                        if(!inq[e.to])  
                        { 
                            Q.push(e.to);  
                            inq[e.to]=true;  
                            if(++cnt[e.to]>n) return true;  
                        }  
                    }  
                }  
            }  
            return false;  
        }  
    }BF;  
    int t;
    int n,m,w;
    int x,y,z;
    int main(){ 
        // freopen("in.txt", "r", stdin);
        // freopen("out.txt", "w", stdout);
        scanf("%d",&t);
        while(t--){
            scanf("%d%d%d",&n,&m,&w);
            BF.init(n);
            for(int i=0;i<m;i++){
                scanf("%d%d%d",&x,&y,&z);
                BF.AddEdge(x-1,y-1,z);
                BF.AddEdge(y-1,x-1,z);
            }
            for(int i=0;i<w;i++){
                scanf("%d%d%d",&x,&y,&z);
                BF.AddEdge(x-1,y-1,-z);
            }
            bool res=BF.negativeCycle(1);
            printf(res==true?"YES
    ":"NO
    ");
        }
        return 0;
    }
  • 相关阅读:
    HDU 2089 不要62
    HDU 5038 Grade(分级)
    FZU 2105 Digits Count(位数计算)
    FZU 2218 Simple String Problem(简单字符串问题)
    FZU 2221 RunningMan(跑男)
    FZU 2216 The Longest Straight(最长直道)
    FZU 2212 Super Mobile Charger(超级充电宝)
    FZU 2219 StarCraft(星际争霸)
    FZU 2213 Common Tangents(公切线)
    FZU 2215 Simple Polynomial Problem(简单多项式问题)
  • 原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/7220766.html
Copyright © 2011-2022 走看看