1. 程式人生 > >CSP201503-4(網路延時)(Java100分)

CSP201503-4(網路延時)(Java100分)

問題描述

  給定一個公司的網路,由n臺交換機和m臺終端電腦組成,交換機與交換機、交換機與電腦之間使用網路連線。交換機按層級設定,編號為1的交換機為根交換機,層級為1。其他的交換機都連線到一臺比自己上一層的交換機上,其層級為對應交換機的層級加1。所有的終端電腦都直接連線到交換機上。
  當資訊在電腦、交換機之間傳遞時,每一步只能通過自己傳遞到自己所連線的另一臺電腦或交換機。請問,電腦與電腦之間傳遞訊息、或者電腦與交換機之間傳遞訊息、或者交換機與交換機之間傳遞訊息最多需要多少步。
輸入格式
  輸入的第一行包含兩個整數n, m,分別表示交換機的臺數和終端電腦的臺數。
  第二行包含n - 1個整數,分別表示第2、3、……、n臺交換機所連線的比自己上一層的交換機的編號。第i臺交換機所連線的上一層的交換機編號一定比自己的編號小。
  第三行包含m個整數,分別表示第1、2、……、m臺終端電腦所連線的交換機的編號。
輸出格式


  輸出一個整數,表示訊息傳遞最多需要的步數。
樣例輸入
4 2
1 1 3
2 1
樣例輸出
4
樣例說明
  樣例的網路連線模式如下,其中圓圈表示交換機,方框表示電腦:
  樣例1
  其中電腦1與交換機4之間的訊息傳遞花費的時間最長,為4個單位時間。
樣例輸入
4 4
1 2 2
3 4 4 4
樣例輸出
4
樣例說明
  樣例的網路連線模式如下:
  樣例2
  其中電腦1與電腦4之間的訊息傳遞花費的時間最長,為4個單位時間。
評測用例規模與約定
  前30%的評測用例滿足:n ≤ 5, m ≤ 5。
  前50%的評測用例滿足:n ≤ 20, m ≤ 20。
  前70%的評測用例滿足:n ≤ 100, m ≤ 100。
  所有評測用例都滿足:1 ≤ n ≤ 10000,1 ≤ m ≤ 10000。
思路:
我的做法是得到每個節點的深度,然後遍歷所有節點,如果節點的度為1,那麼對於該節點,所能得到的最長路徑為孩子的深度+1 ,如果 節點度為0,就不用考慮了,否則,就判斷所有節點的最大和次大深度。最大深度+次大深度就是 以該節點為中介時所能得到的結果。然後全域性變數儲存一個最終結果。

我這兒的深度不完全是指深度(我是按著題目意思來的,其實就是深度-1)因為如果只有一個節點,那麼是一步都不用走的,那麼結果為0,如果有兩個節點,(那麼從下面節點到上面節點也只要走一步,那麼深度分別為1,0) 自己考慮要一下一定能看懂,如果不懂,可以評論, 我一定會幫你解答

package csp_201503_1;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public
class D15_3 { static int dep[]; static Node[] no; static int result=0; public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc = new Scanner(System.in); int n=sc.nextInt(); int m=sc.nextInt(); no=new Node[n+m+1]; dep=new int[n+m+1]; no[1]=new Node(true); for(int i=0;i<dep.length;i++) { dep[i]=-1; } for(int i =2;i<=n;i++) { no[i]=new Node(true); int t=sc.nextInt(); no[t].child.add(i); } for(int i=n+1;i<n+m+1;i++) { no[i]=new Node(false); int t=sc.nextInt(); no[t].child.add(i); dep[i]=0; } get(1); getResult(); System.out.println(result); } private static void getResult() { // TODO Auto-generated method stub for(int i=1;i<no.length;i++) { if(no[i].isExchanger==false) { break; } if(no[i].child.size()==0) { continue; } if(no[i].child.size()==1) { int temp = dep[no[i].child.get(0)]+1; result=Math.max(temp, result); } else { int temp1=dep[no[i].child.get(0)];//存放最大 int temp2=dep[no[i].child.get(1)];//存放次大 if(temp1<temp2) { int temp = temp1; temp1=temp2; temp2=temp; } for(int j=2;j<no[i].child.size();j++) { if(dep[no[i].child.get(j)]>=temp1) { temp2=temp1; temp1=dep[no[i].child.get(j)]; } } result = Math.max(temp2+temp1+2, result); } } } public static void get(int position) {//得到每個節點的深度 if(no[position].child.size()==0) { dep[position]=0; return ; } int max=0; for(int i=0;i<no[position].child.size();i++) { if(dep[no[position].child.get(i)]==-1) { get(no[position].child.get(i)); } max=Math.max(max, dep[no[position].child.get(i)]); } dep[position]=max+1; } } class Node{ boolean isExchanger;//true代表是交換機,false代表是電腦 List<Integer> child; public Node(boolean isExchanger) { super(); this.isExchanger = isExchanger; child = new ArrayList<Integer>();//存放孩子的位置 } }