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\n":"NO\n");
    }
    return 0;
}

 

posted @ 2017-07-22 11:32  勿忘初心0924  阅读(126)  评论(0编辑  收藏  举报