zoukankan      html  css  js  c++  java
  • POJ3259 :Wormholes(SPFA判负环)

    POJ3259 :Wormholes

    时间限制:2000MS 内存限制:65536KByte 64位IO格式:%I64d & %I64u
    描述

    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.

    输入
    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.
    输出
    Lines 1..F: For each farm, output "YES" if FJ can achieve his goal, otherwise output "NO" (do not include the quotes).
    样例输入
    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
    样例输出
    NO
    YES
    提示
    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.
     
    题意:

    FJ的农场有很多虫洞,可以实现时光倒流,现在给你农场每条道路的起点、终点和时间,还有虫洞的起点、终点和能倒流的
    时间,问FJ能不能通过时光倒流看到之前的自己。
    首先T组数据,再输入n,m,w 分别代表n个节点,m个无向边的信息,w个有向虫洞的信息

    思路:

    把w个虫洞当负值加进边就行

    比如第一组数据的3 1 3,在构图的时候add_edge(3,1,-3),即可。

    其实就是用spfa跑一遍图,看一下有没有负环即可。有的话输出YES,没有的话输出NO

    代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<queue>
    #include<cmath>
    #include<vector>
    #include<cstring>
    using namespace std;
    typedef long long LL;
    #define Max_N 1001
    #define INF 100000000
    int head[Max_N],vis[Max_N],n,In[Max_N],cnt;
    int dis[Max_N];
    int pa[Max_N];
    struct note{
        int from,to,next;
        int c;
    }edge[50005*2];
    void init(){
        memset(head,-1,sizeof(head));
        cnt = 0;
    }
    void add_edge(int u,int v,double c){
        edge[cnt].from = u;
        edge[cnt].to = v;
        edge[cnt].c = c;
        edge[cnt].next = head[u];
        head[u] = cnt++;
    }
    bool spfa(int s,int n,int key){
        queue<int>q;
        for(int i = 0 ;i <= n ; i++)
            dis[i] = INF;
        memset(vis,0,sizeof(vis));
        memset(In,0,sizeof(In));
        q.push(s);
        vis[s] = 1;
        dis[s] = 0;
        if(key == -1)
            memset(pa,-1,sizeof(pa));
        while(!q.empty()){
            int p = q.front();
            vis[p] = 0;
            q.pop();
            for(int i = head[p] ; ~i ; i = edge[i].next){
                if(key==i)continue;
                int temp = edge[i].to;
                if(dis[temp] > dis[p] + edge[i].c){
                    dis[temp] = dis[p] + edge[i].c;
                    if(key==-1)
                         pa[temp] = i;
                    if(!vis[temp]){
                        q.push(temp);
                        vis[temp] = 1;
                        if(++In[temp]>n)return false;
                    }
                }
            }
        }
        return true;
    }//spfa带记录路径,通过Key调整
    int main(){
        int m,t,w;
        for(scanf("%d",&t);t--;){
            scanf("%d %d %d",&n,&m,&w);
            init();
            int x,y,c;
            for(int i = 0 ; i < m ; i++){
                scanf("%d %d %d",&x,&y,&c);
                add_edge(x,y,c);
                add_edge(y,x,c);
            }
            for(int i = 0 ; i < w ; i++){
                scanf("%d %d %d",&x,&y,&c);
                add_edge(x,y,-c);
            }
            spfa(1,n,-1)?puts("NO"):puts("YES");
        }
        return 0;
    }
  • 相关阅读:
    AtCoder Beginner Contest 167
    AtCoder Beginner Contest 166
    AtCoder Beginner Contest 165
    AtCoder Beginner Contest 164
    AtCoder Beginner Contest 163
    AtCoder Beginner Contest 162
    AtCoder Beginner Contest 161
    AtCoder Beginner Contest 160
    AtCoder Beginner Contest 159
    自定义Mybatis自动生成代码规则
  • 原文地址:https://www.cnblogs.com/Esquecer/p/8870348.html
Copyright © 2011-2022 走看看