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>();//存放孩子的位置
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值