POJ-3268-DijkStra

POJ-3268-DijkStra
package luogu;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
//描述
//N个农场各一头奶牛(1≤ N≤ 1000)方便编号的1..N将参加在农场#X举行的大型奶牛派对1≤ X≤ N) 。1≤ M≤ 100000)共M单向道路连接两个农场;道路i需要Ti(1≤ Ti≤ 100)穿越的时间单位。
//每头母牛都必须步行去参加聚会,聚会结束后,回到她的农场。每头母牛都很懒,因此可以用最短的时间选择最佳路线。一头母牛的返回路线可能与她最初到达派对的路线不同,因为道路是单向的。
//在所有的奶牛中,一头奶牛往返于派对的最长时间是多少?
//输入
//第1行:三个空格分隔的整数,分别为:N、M和X
//第2..M+1行:第i+1行用三个空格分隔的整数描述道路i:Ai、Bi和Ti。所述道路从农场Ai延伸至农场Bi,需要Ti时间单位来穿越。
//输出
//第1行:一个整数:任何一头牛必须行走的最长时间。
//题意:N头奶牛M条单向道路,到X举行派对,1,N头奶牛到X举行派对,每头母牛都很懒,因此可以用最短的时间选择最佳路线2,举行完派对,返回自己农场,求N头牛中,哪头牛花费最长的时间?
//题解:
//1.从N个农场到X农场求最短距离,即反向建边,求X到N个农场的最短距离
//2.从X农场返回各自农场最短距离,即正向求dijkstra
//最终1和2距离和最大的即是求花费时间最长的奶牛时间
//4 8 2
//1 2 4
//1 3 2
//1 4 7
//2 1 1
//2 3 5
//3 1 2
//3 4 4
//4 2 3
public class POJ3268 {
   static int N,M,X;
   static boolean visited[];
   static int dis[];
   static List<Node2> adjList[];
   static int backDis[];
   static int ans;
   static boolean backVisited[];
   static List<Node2> backList[];
   
   public static void main(String[] args) throws Exception {
        System.setIn(new FileInputStream("src/test/Solution.txt"));
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        while(br.ready()) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            N = Integer.parseInt(st.nextToken());
            M = Integer.parseInt(st.nextToken());
            X = Integer.parseInt(st.nextToken());
            adjList = new List[N+1];
            backVisited = new boolean[N+1];
            visited = new boolean[N+1];
            dis = new int[N+1];
            backDis = new int[N+1];
            backList = new List[N+1];
            Arrays.fill(dis, Integer.MAX_VALUE/2);
            Arrays.fill(backDis, Integer.MAX_VALUE/2);
            Arrays.fill(visited, false);
            Arrays.fill(backVisited, false);
            for (int i = 1; i <= N; i++) {
                adjList[i] = new ArrayList<Node2>();
                backList[i] = new ArrayList<Node2>();
            }
            
            for (int i = 1; i <= M; i++) {
                st = new StringTokenizer(br.readLine());
                int s = Integer.parseInt(st.nextToken());
                int e = Integer.parseInt(st.nextToken());
                int len = Integer.parseInt(st.nextToken());
                adjList[s].add(new Node2(e,len)); //求X农场奶牛到N个农场最短距离,即正向建边,求X到N个农场的最短距离
                backList[e].add(new Node2(s,len));//原本求N个农场奶牛到X农场最短距离,即反向建边,求X到N个农场的最短距离
            }
            
            dijkstra();
            dijkBackStra();
            ans = 0;
            int x = 0;
            for (int i = 1; i <= N; i++) {
                x=Math.max(dis[i]+backDis[i], x);//求花费时间最长的奶牛时间
            }
            ans = x;//任何一头牛必须行走的最长时间。
            System.out.println(ans);
        }
        
   }

   private static void dijkstra() {
       PriorityQueue<Node2> pq = new PriorityQueue<Node2>(11,new Comparator<Node2>() {
        @Override
        public int compare(Node2 o1, Node2 o2) {
            return o1.len-o2.len;
        }
       });
       pq.add(new Node2(X,0));
       dis[X]=0;
       while(!pq.isEmpty()) {
           Node2 curr = pq.poll();
           if(!visited[curr.pos]) {
               visited[curr.pos]=true;
               for (int i = 0; i < adjList[curr.pos].size(); i++) {
                  Node2 next = adjList[curr.pos].get(i);
                  if(next.len+curr.len<dis[next.pos]) {
                      dis[next.pos]=next.len+curr.len;
                      pq.add(new Node2(next.pos,dis[next.pos]));
                  }
               }
           }
       }
   }
   
    private static void dijkBackStra() {
        PriorityQueue<Node2> pqBack = new PriorityQueue<Node2>(11,new Comparator<Node2>() {
        @Override
        public int compare(Node2 o1, Node2 o2) {
            return o1.len-o2.len;
        }
       });
        
       pqBack.add(new Node2(X,0));
       backDis[X]=0;
        while(!pqBack.isEmpty()) {
            Node2 curr = pqBack.poll();
            if(!backVisited[curr.pos]) {
               backVisited[curr.pos]=true;
                for (int i = 0; i < backList[curr.pos].size(); i++) {
                   Node2 next = backList[curr.pos].get(i);
                   if(next.len+curr.len<backDis[next.pos]) {
                      backDis[next.pos]=next.len+curr.len;
                      pqBack.add(new Node2(next.pos,backDis[next.pos]));
                   }
                }
            }
        }
    }

    
}

class Node2{
    int pos;
    int len;
    public Node2(int pos,int len) {
        this.pos = pos;
        this.len=len;
    }
}
View Code

 

POJ-3268-DijkStra

上一篇:Debian 11 (Bullseye) 配置fcitx中文输入法


下一篇:c++智能指针