问题描述
给定一个公司的网络,由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与交换机4之间的消息传递花费的时间最长,为4个单位时间。
样例输入
4 4
1 2 2
3 4 4 4
样例输出
4
样例说明
样例的网络连接模式如下:
其中电脑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>();//存放孩子的位置
}
}