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; } }