题目链接
题目描述
如题,现在有一个并查集,你需要完成合并和查询操作。
输入格式
第一行包含两个整数 N, M,表示共有 N 个元素和 M 个操作。
接下来 M 行,每行包含三个整数 Zi,Xi,Yi。
当 Zi = 1时,将 Xi 与 Yi 所在的集合合并。
当 Zi = 2时,输出 Xi 与 Yi 是否在同一集合内,是的输出 Y ;否则输出 N 。
输出格式
对于每一个 Zi = 2的操作,都有一行输出,每行包含一个大写字母,为 Y 或者 N 。
输入输出样例
输入 #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% 的数据,N ≤ 10,M ≤ 20 。
对于 70% 的数据,N ≤ 100,M ≤ 103。
对于 100% 的数据,1 ≤ N ≤ 104,1 ≤ M ≤ 2 ×105。
AC代码:
(函数详解)
#include <cstdio>
const int maxn = 1e4+5;
int f[maxn], h[maxn];
int n, m, z, x, y;
void Init() {
for(int i=1; i<=n; i++) {
f[i] = i;
h[i] = 0;
}
}
int Find(int x) {
return f[x]==x ? f[x] : f[x] = Find(f[x]);
}
void merge(int a, int b) {
int fa = Find(a);
int fb = Find(b);
if(fa==fb) return;
if(h[fa] < h[fb])
f[fa] = fb;
} else {
f[fb] = fa;
if(h[fa] == h[fb]) h[fa]++;
}
}
int main() {
scanf("%d %d", &n, &m);
Init(); //记住一定要先初始化
// 本题只有一组数据,但若有多组数据,每次都需先进行初始化!!
while(m--) {
scanf("%d %d %d", &z, &x, &y);
if(z==1) {
//由题:当 z为 1时
merge(x,y); //合并两个元素
} else if(z==2) {
//当 z为2时
if(Find(x)==Find(y)) //如果两个元素的根相同
printf("Y\n"); //则输出Y
else //如果两个元素的根不同
printf("N\n"); //则输出N
}
}
return 0;
}