zoukankan      html  css  js  c++  java
  • poj--3259

    ---恢复内容开始---

    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.
     
    题意:John是一个农场主,他的农场出现了虫洞并可以进行时空穿梭,给出农场的虫洞地图,问John是否可以看到原来的自己
    题解:本题可以看作一个单源最短路径问题,首先,可以从一个点开始出发,到达余下的所有节点,其次,这个题目还有负数的权值边,然后就可以用Bellman-Ford算法来求能否
        看到自己了。
    Bellman-Ford算法:
      从单个源点出发,到达余下的节点。这个算法本质是一个动态规划的算法,在算法导论一书中,讲到一个松弛操作就是先对路径的最大距离进行初始化
      for(i=1;i<=n;i++) {dist[i]=INF;}  dist[1]=0;
      算法的实现:
      
    bool bellman_ford()
    {
        for(i=1;i<=n;i++)
            dist[i]=INF;dist[1]=0;
        for(i=1;i<=n;i++)
        {
            bool update=true;
            for(j=1;j<m;j++)
            {
                if(dist[edge[i].to]>dist[edge[i].from+edge[i].cost)
                {
                    dist[edge[i].to]=dist[edge[i].from]+edge[i].cost;//更新dist距离
                       update=false;
                }
            }
            if(update) return false;    
        }
        for(i=0;i<m;i++)
         {
           if(dist[edge[i].to]>dist[edge[i].from+edge[i].cost)//判断是否存在负数环
            return true;
        }    
      return false;  
    }    
    代码:
      
    #include<iostream>
    using namespace std;
    int F,N,M,W;
    int S,E,T;
    struct EDGE{
        int from,to;
        int cost;
    };
    const int INF=100000;
    EDGE edge[10000];
    int dist[510];
    int m;
    bool bellman_ford()
    {
        for(int i=1;i<=N;i++)
        {
            dist[i]=INF;
        }
        dist[1]=0;
        for(int i=1;i<N;i++)
        {
            bool update=true;
            for(int j=0;j<m;j++)
            {
                int u=edge[j].from;
                int v=edge[j].to;
                int t=edge[j].cost;
                
                if(dist[v]>dist[u]+t)
                {
                    dist[v]=dist[u]+t;
                    update=false;
                }
            }
            if(update)    return false;
        }
        for(int i=0;i<m;i++)
        {
            if(dist[edge[i].to]>dist[edge[i].from]+edge[i].cost)
                return true;
        }
        return false;
    }
    int main()
    {
        while(cin>>F)
        {
            while(F--)
            {
                scanf("%d%d%d",&N,&M,&W);
                int u,v,t;
                m=0;
                for(int i=1;i<=M;i++)
                {
                    scanf("%d%d%d",&u,&v,&t);
                    edge[m].from=u;
                    edge[m].to=v;
                    edge[m++].cost=t;
                    
                    edge[m].from=v;
                    edge[m].to=u;
                    edge[m++].cost=t;
                }
                for(int i=1;i<=W;i++)
                {
                    scanf("%d%d%d",&u,&v,&t);
                    edge[m].from=u;
                    edge[m].to=v;
                    edge[m++].cost=-t;
                }
                if(bellman_ford())    printf("YES
    ");
                else printf("NO
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    C89:论内存泄漏
    C++03:模板
    C++的STL(标准模板库)系列:容器——string容器
    C++03:论类的友元函数和内联函数
    C++03:论类的运算符重载
    Windows开发:网络编程基础
    Windows开发:论文件和权限
    C89:头文件
    C89:论符号
    纪录片(深度好片)
  • 原文地址:https://www.cnblogs.com/acmblog/p/9606776.html
Copyright © 2011-2022 走看看