zoukankan      html  css  js  c++  java
  • POJ 3259:Wormholes

    Description

    John农夫拥有许多农场,John发现了许多神奇的树洞。这些树洞 都非常特殊因为进入树洞后能够把你送到一个目的地,并且到达目的地时的时间早于你进入树洞时的时间(比如你进入洞时是2000年,但是出洞时发现是1990年)。每个农场都有N(1<=N<=500)个field,记为1...N,M(1<=M<=2500)条path,W(1<=W<=200)个wormhole。
     
    John是一个很喜欢穿越的人,他想从某个区域进入,并且经过一系列的路径或树洞 ,最后到达起点,并且到达起点时发现比最初在起点的时间还早。
     
    为了帮助John实现这个愿望,他提供给我们他的F(1<=F<=5)个farm的地图。已知穿过每一条path的时间都小于等于10000s,穿过每个树洞所倒退的时间小于等于10000s。

    Input

    第一行是farm的个数。
    第二行是第一个farm的field个数N,path的个数M,树洞的个数W。
    第3~M+2 行是 path 的起点、终点、穿越时间(注意,这里的path都是双向边)
    第M+3~M+W+2 行是树洞的起点、终点、倒退时间(单向边)
    接着是第二个farm。
     

    Output

    对于每个farm,如果这个farm能够达成目标,则输出“YES”,否则输出“NO"。

    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

    对于 Sample Input :

    farm 1 不能够达到目标。

    farm 2 能够,因为 1->2->3->1,他回到1时比原来提前了1秒。

    算法思想

    将field作为节点,path作为正权边,wormholes作为负权边,注意:path是双向边。

    第一步:添加一个虚拟源点s,并将这个虚拟源点连向所有的节点(field),因此共有N+1个节点,2*M+W+N条边。

    第二步:对虚拟源点s运行Bellman-Ford算法,判断是否有源点可达负圈即可。

    算法实现

      1   2 
      3 import java.util.Scanner;
      4 
      5 public class Main {
      6     int n;            // 节点个数
      7     int m;            // 边的个数
      8     int head[];        // head[i] 表示节点i指向的第一条边的索引是多少
      9     int edge[][];    // edge[i]表示第i条边 ,edge[i][1]表示这条边的起点,edge[i][2]表示这条边的终点,edge[i][3]表示这条边的权重
     10     int next[];        // next[i]表示第i条边在邻接表中的下一条边是什么
     11     int d[];        // d[i]表示第i条边的d值 
     12     
     13     int farmNumber;
     14     int N[];
     15     int M[];
     16     int W[];
     17     int current_farm = 0;
     18     
     19     public void getSingleFarm(Scanner in){
     20         int current_edge = 0;
     21         N[current_farm] = in.nextInt();
     22         M[current_farm] = in.nextInt();
     23         W[current_farm] = in.nextInt();
     24         this.n = N[current_farm]+1;
     25         this.m = 2*M[current_farm]+W[current_farm]+N[current_farm];
     26         //2*M+W+N条边
     27         head = new int[n];
     28         edge = new int[m][4];
     29         next = new int[m];
     30         d = new int[n];
     31         for(int i=0;i<n;i++){
     32             head[i] = -1;
     33         }
     34         for(int i=1;i<=N[current_farm];i++){
     35             edge[current_edge][1] = 0;
     36             edge[current_edge][2] = i;
     37             edge[current_edge][3] = 0;
     38             next[current_edge] = head[0];
     39             head[0] = current_edge;
     40             current_edge++;
     41         }
     42         for(int i=1;i<=M[current_farm];i++){
     43             int from = in.nextInt();
     44             int to = in.nextInt();
     45             int cost = in.nextInt();
     46             edge[current_edge][1] = from;
     47             edge[current_edge][2] = to;
     48             edge[current_edge][3] = cost;
     49             next[current_edge] = head[from];
     50             head[from] = current_edge;
     51             current_edge++;
     52             
     53             edge[current_edge][1] = to;
     54             edge[current_edge][2] = from;
     55             edge[current_edge][3] = cost;
     56             next[current_edge] = head[to];
     57             head[to] = current_edge;
     58             current_edge++;
     59         }
     60         for(int i=1;i<=W[current_farm];i++){
     61             int from = in.nextInt();
     62             int to = in.nextInt();
     63             int cost = in.nextInt();
     64             edge[current_edge][1] = from;
     65             edge[current_edge][2] = to;
     66             edge[current_edge][3] = -cost;
     67             next[current_edge] = head[from];
     68             head[from] = current_edge;
     69             current_edge++;
     70         }
     71         current_farm++;
     72     }
     73     public void getInput(Scanner in){
     74         
     75         farmNumber = in.nextInt();
     76         N = new int[farmNumber];
     77         M = new int[farmNumber];
     78         W = new int[farmNumber];
     79         
     80         for(int i=1;i<=farmNumber;i++){
     81             getSingleFarm(in);
     82             boolean flag = BellmanFord(0);
     83             if(flag) System.out.println("NO");
     84             else System.out.println("YES");
     85             
     86         }
     87     }
     88     
     89     public boolean BellmanFord(int s){
     90         for(int i=0;i<n;i++){
     91             d[i] = Integer.MAX_VALUE;
     92         }
     93         d[s] = 0;
     94         boolean flag = true;
     95         for(int t=1;t<=n-1;t++){
     96             if(flag){
     97                 flag = false;
     98                 for(int i=0;i<n;i++){
     99                     for(int j=head[i];j!=-1;j=next[j]){
    100                         if(d[edge[j][2]]>d[i]+edge[j][3]){
    101                             d[edge[j][2]] = d[i] + edge[j][3];
    102                             flag = true;
    103                         }
    104                     }
    105                 }
    106             }
    107         }
    108         for(int i=0;i<n;i++){
    109             for(int j=head[i];j!=-1;j=next[j]){
    110                 if(d[edge[j][2]]>d[i]+edge[j][3]){
    111                     return false;
    112                 }
    113             }
    114         }
    115         return true;
    116     }
    117     
    118     public static void main(String[] args) {
    119         Main main = new Main();
    120         main.getInput(new Scanner(System.in));
    121         
    122     }
    123 }
    作者:xiazdong
    出处:http://blog.xiazdong.info
    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
  • 相关阅读:
    安装maven报错及解决
    Servlet包导入
    理解SQL SERVER的逻辑读,预读和物理读以及索引
    第六章(函数)编程题二
    第六章(函数)编程题一
    第五章(使用对象) 编程题一
    第三章(循环) 编程题 4
    第四章(数组) 编程题 1
    第三章(循环) 编程题 3
    低功耗蓝牙 ATT/GATT/Service/Characteristic 规格解读
  • 原文地址:https://www.cnblogs.com/xiazdong/p/3057240.html
Copyright © 2011-2022 走看看