题目所属分类
维护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];
}
}