java---并查集算法---合并集合(每日一道算法2022.8.12)

题目
一共有 n 个数,编号是 1∼n,最开始每个数各自在一个集合中
现在要进行 m 个操作,操作共有两种:

M a b,将编号为 a 和 b 的两个数所在的集合合并,如果两个数已经在同一个集合中,则忽略这个操作
Q a b,询问编号为 a 和 b 的两个数是否在同一个集合中

输入
4 5
M 1 2
M 3 4
Q 1 2
Q 1 3
Q 3 4

输出
Yes
No
Yes
public class 并查集_合并集合 {
    //初始化
    public static int N = 100010;
    public static int[] p = new int[N];

    public static void main(String[] args) throws IOException{
        //初始化,接收n和m
        //将每个元素的根节点都先指向自己,注意是i是1开始
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String[] init_data = in.readLine().split(" ");
        int n = Integer.parseInt(init_data[0]), m = Integer.parseInt(init_data[1]);
        for (int i = 1; i<=n; i++){p[i] = i;}

        //执行操作
        while (m-- > 0) {
            String[] data_arr = in.readLine().split(" ");

            //这里将模式参数和两个int参数分出来
            String model = data_arr[0];
            int x = Integer.parseInt(data_arr[1]), y = Integer.parseInt(data_arr[2]);

            //直接将一棵树的根节点指向另一颗树,这样就完成了合并两个树的操作
            if (model.equals("M")){p[find(x)] = find(y);}
            else if (model.equals("Q")) {
                if (find(x)==find(y)) {System.out.println("Yes");}
                else {System.out.println("No");}
            }
        }
    }

    //并查集加路径优化,所有的节点直接指向根节点,而不是指向上一个元素,将时间压缩到近乎O(1)
    public static int find(int x){
        if (p[x]!=x) {p[x] = find(p[x]);}
        return p[x];
    }
}

声明:算法思路来源为y总,详细请见https://www.acwing.com/
本文仅用作学习记录和交流

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值