首页 > 代码库 > poj 3259 Wormholes 判断负权值回路

poj 3259 Wormholes 判断负权值回路

Wormholes

Time Limit: 2000 MS Memory Limit: 65536 KB

64-bit integer IO format: %I64d , %I64u   Java class name: Main

[Submit] [Status] [Discuss]

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..N, M (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, F. F farm descriptions follow. Line 1 of each farm: Three space-separated integers respectively: N, M, and W Lines 2..M+1 of each farm: Three space-separated numbers (S, E, T) 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 (S, E, T) 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

23 3 11 2 21 3 42 3 13 1 33 2 11 2 32 3 43 1 8

Sample Output

NOYES

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.
//Memory Time//308K   204MS#include<iostream>#include <string.h>using namespace std;int dis[1001];      //源点到各点权值const int max_w=10001;      //无穷远struct weight{    int s;    int e;    int t;}edge[5200];int N,M,W_h; //N (1≤N≤500)fields 顶点数             //M (1≤M≤2500)paths 正权双向边             //W_h (1≤W≤200) wormholes 虫洞(回溯),负权单向边int all_e;   //边集(边总数)bool bellman(){    bool flag;    /*relax*/    for(int i=0;i<N-1;i++)  ///dis松弛的次数    {        flag=false;        for(int j=0;j<all_e;j++) ///所有边集            if(dis[edge[j].e] > dis[edge[j].s] + edge[j].t)  ///可以松弛  更新            {                dis[edge[j].e] = dis[edge[j].s] + edge[j].t;                flag=true;         //relax对路径有更新            }        if(!flag)            break;  //只要某一次relax没有更新,说明最短路径已经查找完毕,或者部分点不可达,可以跳出relax    }///已经更新完毕了 所有边集都是两点之间的最短路    /*Search Negative Circle*/    for(int k=0;k<all_e;k++) ///遍历所有边集 如果还出现能够再次更新成最短的边  就表明出现负权值回路了        if( dis[edge[k].e] > dis[edge[k].s] + edge[k].t)            return true;    return false;}int main(void){    int u,v,w;    int F;    cin>>F;    while(F--)    {        memset(dis,max_w,sizeof(dis));    //源点到各点的初始值为无穷,即默认不连通        cin>>N>>M>>W_h;        all_e=0;      //初始化指针        /*read in Positive Paths*/        for(int i=1;i<=M;i++)        {            cin>>u>>v>>w;            edge[all_e].s=edge[all_e+1].e=u;            edge[all_e].e=edge[all_e+1].s=v;            edge[all_e++].t=w;            edge[all_e++].t=w;               //由于paths的双向性,两个方向权值相等,注意指针的移动        }        /*read in Negative Wormholds*/        for(int j=1;j<=W_h;j++)        {            cin>>u>>v>>w;            edge[all_e].s=u;            edge[all_e].e=v;            edge[all_e++].t=-w;     //注意权值为负        }        /*Bellman-Ford Algorithm*/        if(bellman())            cout<<"YES"<<endl;        else            cout<<"NO"<<endl;    }    return 0;}//Memory Time//308K   204MS#include<iostream>#include <string.h>using namespace std;int dis[1001];      //源点到各点权值const int max_w=10001;      //无穷远struct weight{    int s;    int e;    int t;}edge[5200];int N,M,W_h; //N (1≤N≤500)fields 顶点数             //M (1≤M≤2500)paths 正权双向边             //W_h (1≤W≤200) wormholes 虫洞(回溯),负权单向边int all_e;   //边集(边总数)bool bellman(){    bool flag;    /*relax*/    for(int i=0;i<N-1;i++)  ///dis松弛的次数    {        flag=false;        for(int j=0;j<all_e;j++) ///所有边集            if(dis[edge[j].e] > dis[edge[j].s] + edge[j].t)  ///可以松弛  更新            {                dis[edge[j].e] = dis[edge[j].s] + edge[j].t;                flag=true;         //relax对路径有更新            }        if(!flag)            break;  //只要某一次relax没有更新,说明最短路径已经查找完毕,或者部分点不可达,可以跳出relax    }///已经更新完毕了 所有边集都是两点之间的最短路    /*Search Negative Circle*/    for(int k=0;k<all_e;k++) ///遍历所有边集 如果还出现能够再次更新成最短的边  就表明出现负权值回路了        if( dis[edge[k].e] > dis[edge[k].s] + edge[k].t)            return true;    return false;}int main(void){    int u,v,w;    int F;    cin>>F;    while(F--)    {        memset(dis,max_w,sizeof(dis));    //源点到各点的初始值为无穷,即默认不连通        cin>>N>>M>>W_h;        all_e=0;      //初始化指针        /*read in Positive Paths*/        for(int i=1;i<=M;i++)        {            cin>>u>>v>>w;            edge[all_e].s=edge[all_e+1].e=u;            edge[all_e].e=edge[all_e+1].s=v;            edge[all_e++].t=w;            edge[all_e++].t=w;               //由于paths的双向性,两个方向权值相等,注意指针的移动        }        /*read in Negative Wormholds*/        for(int j=1;j<=W_h;j++)        {            cin>>u>>v>>w;            edge[all_e].s=u;            edge[all_e].e=v;            edge[all_e++].t=-w;     //注意权值为负        }        /*Bellman-Ford Algorithm*/        if(bellman())            cout<<"YES"<<endl;        else            cout<<"NO"<<endl;    }    return 0;}

 

poj 3259 Wormholes 判断负权值回路