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;
    }
  • 相关阅读:
    SQL注入
    mysq笔记
    白话内存管理(一):从开国大典说起
    【转载】光纤协议中 WWPN 编码规则及实例解析
    利用django打造自己的工作流平台(三):任务的批量分派和跟踪
    利用django打造自己的工作流平台(二):疫情统计系统
    利用django打造自己的工作流平台(一):从EXCEL到流程化运作
    驾驭git merge——git merge的规范化操作
    一款用于绘制状态机转换图和流程图的web在线绘图工具
    利用python+graphviz绘制数据结构关系图和指定目录下头文件包含关系图
  • 原文地址:https://www.cnblogs.com/Esquecer/p/8870348.html
Copyright © 2011-2022 走看看