Wormholes

http://poj.org/problem?id=3259,简单的图论题目,判断有无负权回路

Wormholes
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 37258 Accepted: 13694

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.
下面是spfa(适用于稀疏图)的代码跟ford的代码

Source Code

Problem: 3259 User: hnust_xiaoqi
Memory: 280K Time: 157MS
Language: C++ Result: Accepted
  • Source Code
    #include <cstdio>
    #include <vector>
    #include <queue>
    #include <cstring>
    using namespace std;
    const int maxn=1<<30;
    #define N 510
    struct edge{
        int e;
        int w;
        edge(int ee,int ww):e(ee),w(ww){}
        edge(){}
    };
    vector<vector<edge> >v;
    int n,m,w;
    bool spfa(){
        int dis[N];
        int used[N];
        memset(used,0,sizeof(used));
        for(int i=1;i<=n;i++)
            dis[i]=maxn;
        dis[1]=0;
        queue<int>q;
        q.push(1);
        while(!q.empty()){
            int S=q.front();
            q.pop();
            for(int i=0;i<v[S].size();i++){
                int e=v[S][i].e;
                if(dis[e]>dis[S]+v[S][i].w){
                    dis[e]=dis[S]+v[S][i].w;
                    q.push(e);
                    used[e]++;
                    if(used[e]>=n)return true;
                }
            }
        }
        return false;
    }
    int main()
    {
        //freopen("F:in.txt","r",stdin);
        int T;
        scanf("%d",&T);
        while(T--){
              scanf("%d%d%d",&n,&m,&w);
              int s,e,t;
              v.clear();
              v.resize(n+1);
              for(int i=0;i<m;i++){
                scanf("%d%d%d",&s,&e,&t);
                v[s].push_back(edge(e,t));
                v[e].push_back(edge(s,t));
              }
              for(int i=0;i<w;i++){
                scanf("%d%d%d",&s,&e,&t);
                v[s].push_back(edge(e,-t));
              }
              if(spfa())printf("YES\n");
              else printf("NO\n");
        }
        return 0;
    }

比较慢,

Source Code

Problem: 3259 User: hnust_xiaoqi
Memory: 316K Time: 79MS
Language: C++ Result: Accepted
  • Source Code
    #include <cstdio>
    #include <cstring>
    #include <vector>
    using namespace std;
    const int max1=1<<30;
    struct edge{
        int u;
        int v;
        int w;
        edge(int uu,int vv,int ww):u(uu),v(vv),w(ww){}
        edge(){}
    };
    vector<edge>v;
    int n,m,w;
    //int v[N*10];
    bool bellman_ford(int x){
        int dis[1000];
        for(int i=1;i<=n;i++)
            dis[i]=max1;
        dis[x]=0;
        bool flag;
        for(int i=1;i<n;i++){
                flag=false;
            for(int j=0;j<v.size();j++)
            {
                int s=v[j].u;
                int e=v[j].v;
                int w=v[j].w;
                if(dis[e]>dis[s]+w){
                    dis[e]=dis[s]+w;
                    flag=true;
                }
            }
            if(!flag)break;
        }
        for(int i=0;i<v.size();i++){
            int s=v[i].u;
            int e=v[i].v;
            int w=v[i].w;
            if(dis[s]+w<dis[e])return true;
        }
        return false;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--){
            //int u[N],v[N],w[N],dis[N];
            v.clear();
            int s,e,t;
            scanf("%d%d%d",&n,&m,&w);
            for(int i=0;i<m;i++)
            {
                scanf("%d%d%d",&s,&e,&t);
                v.push_back(edge(s,e,t));
                v.push_back(edge(e,s,t));
            }
            for(int i=0;i<w;i++){
                scanf("%d%d%d",&s,&e,&t);
                v.push_back(edge(s,e,-t));
            }
            if(bellman_ford(1))
                printf("YES\n");
            else printf("NO\n");
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值