촌수 계산 练习 java实现

题目连接:촌수 계산--计算距离

题目类型是LCA.

代码:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
 
class source {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        st = new StringTokenizer(br.readLine());
        int A = Integer.parseInt(st.nextToken());
        int B = Integer.parseInt(st.nextToken());
 
        st = new StringTokenizer(br.readLine());
        int M = Integer.parseInt(st.nextToken());
        int[] preArray = new int[N+1];//数组存放当前节点的父节点
        for(int i = 1;i<=M;i++){
            st = new StringTokenizer(br.readLine());
            int pre = Integer.parseInt(st.nextToken());
            int next = Integer.parseInt(st.nextToken());
            preArray[next] = pre;
        }
 
        if(A == B){
            System.out.println(0);
            return;
        }
 
        int[] AB = get(preArray,A,B);
        int[] BA = get(preArray,B,A);
        int result = -1;
        if(AB[0]!=BA[0]){
            System.out.println(-1);
        }
        else if(AB[1]==1 || BA[1]==1){
            System.out.println(Math.abs(AB[2]-BA[2]));
        }
        else{
            System.out.println(AB[2]+BA[2]-2*getParentLevel(preArray,AB,A,BA,B));
        }
 
    }
    //这个方法是为了找到最下公共父节点的层级
    //返回值为公共父节点的层级.
    //将两个节点处理到同一层后,向上找父节点
    private static int getParentLevel(int[] preArray,int[] AB,int ANum,int[] BA,int BNum){
        int[] A  = Arrays.copyOf(AB,AB.length);
        int[] B = Arrays.copyOf(BA,BA.length);
        if(A[2] > B[2]){
            while(A[2]!=B[2]){
                A[2]--;
                ANum = preArray[ANum];
            }
        }
        else if(B[2] > A[2]){
            while(A[2]!=B[2]){
                B[2]--;
                BNum = preArray[BNum];
            }
        }
        int level = A[2];
        while(preArray[ANum]!=preArray[BNum]){
            ANum = preArray[ANum];
            BNum = preArray[BNum];
            level--;
        }
        level-=1;
        return level;
    }
    //这个方法第一个参数为父节点数组,当前节点为数组下标,值为父节点
    //target是要搜索的节点
    //judge是另外一个节点编号
    //在搜索过程中判断judge节点是否在target向上搜索的路径上
    //返回值[0]是target的root节点,[1]是judge是否在搜索路径上,[2]是target相对于root节点的level(层级)
    private static int[] get(int[] preArray,int target,int judge){
        int [] result = new int[3];
        int level = 0;
        while(preArray[target]!=0){
            level++;
            target = preArray[target];
            if(target == judge){
                result[1] = 1;
            }
        }
        result[0] = target;
        result[2] = level;
        return result;
    }
}

 

posted @ 2021-04-30 16:22  Monstro  阅读(49)  评论(0)    收藏  举报