CSP201503-4(网络延时)(Java100分)

版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/qq_24681499/article/details/81218091

问题描述

  给定一个公司的网络,由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>();//存放孩子的位置
    }
}

猜你喜欢

转载自blog.csdn.net/qq_24681499/article/details/81218091
今日推荐