• POJ 3259 Wormholes (floyd或者spfa)


    Wormholes

    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 58636   Accepted: 21921

    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

     
    题意有点神经病,就是一个人有f个农场,农场里有n个坑,m个正常坑,w个虫洞,虫洞可以让牛回到t秒前,问这个农场存不存在可以让牛无限回到过去的情况(就是负环)。那么说白了判负环是否存在。最直接的思路就是spfa跑一遍,松弛的点大于等于n就特判跳出。(有人floyd也ac了,一看时间限制2s,确实可以,但是跑出来比spfa慢很多)。
    //#include<bits/stdc++.h>
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<vector>
    #include<cmath>
    #include<iostream>
    using namespace std;
    #define maxn 3005
    #define INF 99999999
    typedef pair<int,int> pii;
    vector<pii> e[maxn];
    int d[maxn],vis[maxn],cnt[maxn];
    int f,n,m,w,ans;
    
    void init()
    {
        for(int i=0; i<maxn; i++) e[i].clear();
        for(int i=0; i<maxn; i++) d[i]=INF;
        memset(vis,0,sizeof(vis));
        memset(cnt,0,sizeof(cnt));
    }
    
    void addedge(int x,int y,int z)
    {
        e[x].push_back(make_pair(y,z));
        // e[y].push_back(make_pair(x,z));
    }
    
    void spfa(int s)
    {
        queue<int> q;
        d[s]=0;
        vis[s]=1;
        cnt[s]++;
        q.push(s);
        while(!q.empty())
        {
            int now=q.front();
            q.pop();
            vis[now]=0;
            for(int i=0; i<e[now].size(); i++)
            {
                int v=e[now][i].first;
                int w=e[now][i].second;
                if(d[v]>d[now]+w)
                {
                    d[v]=d[now]+w;
                    if(!vis[v])
                    {
                        vis[v]=1;
                        cnt[v]++;
                        q.push(v);
                        if(cnt[v]>=n)
                        {
                            ans=1;
                            return;
                        }
                    }
                }
            }
        }
    }
    
    
    
    int main()
    {
        scanf("%d",&f);
        while(f--)
        {
            init();
            ans=0;
            scanf("%d %d %d",&n,&m,&w);
            while(m--)
            {
                int x,y,z;
                scanf("%d %d %d",&x,&y,&z);
                addedge(x,y,z);
                addedge(y,x,z);
            }
            while(w--)
            {
                int x,y,z;
                scanf("%d %d %d",&x,&y,&z);
                addedge(x,y,-z);
            }
            spfa(1);
            if(ans)
                printf("YES
    ");
            else
                printf("NO
    ");
        }
    
    
        return 0;
    }
    View Code
  • 相关阅读:
    21.满足条件的01序列 卡特兰数
    20.求组合数 IV
    19.求组合数 III
    18.求组合数 II
    17.求组合数 I
    14.表达整数的奇怪方式 中国剩余定理 --------待复习标志--------
    16.高斯消元解异或线性方程组
    15.高斯消元解线性方程组
    writing: improvised lecture
    writing: a lesson about coronavirus epidemic
  • 原文地址:https://www.cnblogs.com/youchandaisuki/p/8826123.html
Copyright © 2020-2023  润新知