蓝桥杯JAVA-27.并查集-维护每个节点到根节点的距离(补充)

蓝桥杯复习知识点汇总

描述

给出n个点,n-1个关系。关系有两个数a、b,表示a是b的父节点。

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author DragonOne
 * @Date 2021/12/5 21:27
 * @墨水记忆 www.tothefor.com
 */

public class Main {
    public static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    public static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
    public static StreamTokenizer cin = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    public static PrintWriter cout = new PrintWriter(new OutputStreamWriter(System.out));
    public static Scanner sc = new Scanner(System.in);
    /**
     * 每月的天数
     */
    public static int monthes[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    public static int maxd = 200000000 + 15;
    public static int INF = 0x3f3f3f3f;
    public static int mod = (int) 1e9 + 7;
    public static int[][] fx = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
    public static int[] par = new int[maxd]; //par[i]表示i的父节点
    public static int[] dis = new int[maxd]; //dis[i]表示i到根节点的距离

    public static int find(int x){
        if(par[x]!=x){
            int t = par[x];
            par[x]=find(par[x]);
            dis[x]+=dis[t]; //x到根节点的距离 就等于 x到父节点的距离 加上 x的父节点到根节点的距离。之所以有x到父节点的距离,是因为在最开始赋的就是x到父节点的距离
//            return par[x];
        }
        return par[x];
    }

    public static void main(String[] args) throws Exception {

        int n = nextInt();
        for(int i=1;i<=n;++i) par[i] = i;
        for(int i=1;i<=n-1;++i){
            int x = nextInt();
            int y = nextInt();
            par[y]=x; //x是y的父节点
            dis[y]=1; //当y最开始赋父节点时,默认此时的父节点就是他的根节点,就更新到根节点的距离为1,然后当需要查询他到根节点的距离时,在查询方法中就会更新至到真正根节点的距离。
        }
        for(int i=1;i<=n;++i) {
            int p = find(i);
            System.out.println(i+" 到 "+p+" 的距离为:"+dis[i]);
        }
/**
 * 5
 * 1 2
 * 1 5
 * 2 3
 * 2 4
 *
 * 输出
 * 1 到 1 的距离为:0
 * 2 到 1 的距离为:1
 * 3 到 1 的距离为:2
 * 4 到 1 的距离为:2
 * 5 到 1 的距离为:1
 */

        closeAll();
    }

    public static int gcd(int a, int b) { // 不需要判断a和b的大小
        while (b > 0) {
            a %= b;
            b ^= a;
            a ^= b;
            b ^= a;
        }
        return a;
    }

    public static int log(int x) { //log方法是以2为底,求x的对数.而java自带的log是以e为底的
        return (int) (Math.log(x) / Math.log(2));
    }

    public static void cinInit() {
        cin.wordChars('a', 'z');
        cin.wordChars('A', 'Z');
        cin.wordChars(128 + 32, 255);
        cin.whitespaceChars(0, ' ');
        cin.commentChar('/');
        cin.quoteChar('"');
        cin.quoteChar('\'');
        cin.parseNumbers(); //可单独使用还原数字
    }

    public static int nextInt() throws Exception {
        cin.nextToken();
        return (int) cin.nval;
    }

    public static long nextLong() throws Exception {
        cin.nextToken();
        return (long) cin.nval;
    }

    public static double nextDouble() throws Exception {
        cin.nextToken();
        return cin.nval;
    }

    public static String nextString() throws Exception {
        cin.nextToken();
        return cin.sval;
    }

    public static void closeAll() throws Exception {
        cout.close();
        in.close();
        out.close();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值