acwing 837. 连通块中点的数量-java

题目所属分类

维护size的并查集模板:


    int p[N], size[N];
    //p[]存储每个点的祖宗节点, 
    //size[]只有祖宗节点的有意义,表示祖宗节点所在集合中的点的数量

    // 返回x的祖宗节点
    int find(int x)
    {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }

    // 初始化,假定节点编号是1~n
    for (int i = 1; i <= n; i ++ )
    {
        p[i] = i;
        size[i] = 1;
    }

    // 合并a和b所在的两个集合:
    size[find(b)] += size[find(a)];
    p[find(a)] = find(b);



 

原题链接

在这里插入图片描述

代码案例:输入样例:
5 5
C 1 2
Q1 1 2
Q2 1
C 2 5
Q2 5
输出样例:
Yes
2
3

题解

在这里插入图片描述
size[]只有祖宗节点的有意义,表示祖宗节点所在集合中的点的数量
也就是说只有根节点的那个点有意义

import java.util.Scanner;
public class Main{
    static int N = 100010;
    static int[] p = new int[N];
    static int[] size = new int[N];
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int m = scan.nextInt();
        for(int i = 0 ; i < n ; i++){
            p[i] = i;
            size[i] = 1 ;//每一个集合元素的个数
        }
        while(m-- > 0){
            String s = scan.next();
            
            if(s.equals("C")){
                int a = scan.nextInt();
                int b = scan.nextInt();
                if(find(a) != find(b)){//进行合并 
                //这两个顺序不能换  要先进行根节点的数量相加  在把a的祖先结点的父节点 加到b的祖先节点
                //如果要先进行合并P的话 要提前用int x = find(b); int y = find(a)这样提前保存好 
                //否则先合上之后用这样会发生变化
                    size[find(b)] += size[find(a)] ;
                    p[find(a)] = find(b) ;
                }
                 
            }
            else if(s.equals("Q1")){//进行查询
                int a = scan.nextInt();
                int b = scan.nextInt();
                if(find(a) == find(b))System.out.println("Yes");
                else System.out.println("No");
            }else {
                int a = scan.nextInt();
                System.out.println(size[find(a)]);
            }
        }
    }
   public  static int find(int x){//找祖宗节点
        if(p[x] != x){
            p[x] = find(p[x]);
        }
        return p[x];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

依嘫_吃代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值