洛谷 P3367 【模板】并查集 (Java)
传送门:P3367 【模板】并查集
题目:【模板】并查集
题目描述
如题,现在有一个并查集,你需要完成合并和查询操作。
输入格式
第一行包含两个整数 N , M N,M N,M ,表示共有 N N N 个元素和 M M M 个操作。
接下来 M M M 行,每行包含三个整数 Z i , X i , Y i Z_i,X_i,Y_i Zi,Xi,Yi 。
当 Z i = 1 Z_i=1 Zi=1 时,将 X i X_i Xi 与 Y i Y_i Yi 所在的集合合并。
当
Z
i
=
2
Z_i=2
Zi=2 时,输出
X
i
X_i
Xi 与
Y
i
Y_i
Yi 是否在同一集合内,是的输出
Y
;否则输出 N
。
输出格式
对于每一个
Z
i
=
2
Z_i=2
Zi=2 的操作,都有一行输出,每行包含一个大写字母,为 Y
或者 N
。
样例 #1
样例输入 #1
4 7
2 1 2
1 1 2
2 1 2
1 3 4
2 1 4
1 2 3
2 1 4
样例输出 #1
N
Y
N
Y
提示
对于 30 % 30\% 30% 的数据, N ≤ 10 N \le 10 N≤10, M ≤ 20 M \le 20 M≤20。
对于 70 % 70\% 70% 的数据, N ≤ 100 N \le 100 N≤100, M ≤ 1 0 3 M \le 10^3 M≤103。
对于 100 % 100\% 100% 的数据, 1 ≤ N ≤ 1 0 4 1\le N \le 10^4 1≤N≤104, 1 ≤ M ≤ 2 × 1 0 5 1\le M \le 2\times 10^5 1≤M≤2×105, 1 ≤ X i , Y i ≤ N 1 \le X_i, Y_i \le N 1≤Xi,Yi≤N, Z i ∈ { 1 , 2 } Z_i \in \{ 1, 2 \} Zi∈{1,2}。
分析:
实现了一个并查集的数据结构,并对给定的一系列操作进行处理。
定义全局变量:
N:表示最大元素数量。
p:表示并查集的数组,用于存储每个元素的父节点。
n 和 m:分别表示元素数量和操作数量。
查找方法 find(int x):该方法用于找到元素x所在集合的根节点(即祖先节点)。通过递归查找x的父节点,直到找到根节点,同时进行路径压缩,即将查找路径上的所有节点的父节点都直接指向根节点,以减少后续查找的时间。
合并方法 union(int x, int y):该方法将两个元素所在的集合合并。首先找到x和y的根节点(即各自集合的代表元素),如果它们的根节点不同,则将其中一个集合的根节点指向另一个集合的根节点,实现合并操作。
查询方法 sear(int x, int y):该方法用于判断元素x和y是否属于同一个集合。首先找到x和y的根节点,然后比较它们的根节点是否相同,若相同则说明它们在同一个集合中,返回true,否则返回false。
主函数main():
初始化并查集数组p,使每个元素初始时都指向自己。
循环读取每个操作:
如果操作为1,则读取两个元素x和y,执行合并操作。
如果操作为2,则读取两个元素x和y,执行查询操作,并根据查询结果输出相应的结果。
代码:
import java.util.Scanner;
public class Main {
static final int N = 10010;
static int [] p = new int [N];
static int n,m;
// 合并
public static void union(int x,int y) {
int rootx = find(x);
int rooty = find(y);
if(rootx!=rooty) p[rootx] = rooty;
}
// 找到x的祖宗节点
public static int find(int x) {
if(p[x]!=x) p[x] = find(p[x]);
return p[x];
}
// 查询
public static boolean sear(int x,int y) {
int rootx = find(x);
int rooty = find(y);
return rootx==rooty;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();m = sc.nextInt();
for(int i = 1;i <= n;i++) p[i] = i;
int z,x,y;
while(m-->0) {
z = sc.nextInt();x = sc.nextInt();y = sc.nextInt();
if(z==1) {//union
union(x,y);
}else {//search
if(sear(x,y)) System.out.println("Y");
else System.out.println("N");
}
}
}
}