题目描述
本次上机的D题,是一道并查集的板子题,数据很弱,不优化也可以直接AC。
并查集
一种表示元素与元素之间是否存在关系的数据结构,简洁且高效。
基本格式
int fa[MAX],rank[MAX];
int find (int x)
{
return x==fa[x]?x:find(fa[x]);
}
将寻找结果设置为x的祖先节点fa[x].
路径压缩
int fa[MAX],rank[MAX];
int find (int x)
{
return x==fa[x]?x:(fa[x]=find(fa[x]));
}
按秩合并
void merge(int i,int j){
int x = find(i),y = find(j);
if(rank[x]<=rank[y]){
fa[x] = y;
}
else fa[y] = x;
if(rank[x]==rank[y]&&x!=y) rank[y]++;
}
路径压缩和按秩合并有一定冲突,最好不要同时使用。
AC代码
/*
Author: 李昊
Result: AC Submission_id: 3846248
Created at: Sun Nov 21 2021 19:59:15 GMT+0800 (China Standard Time)
Problem_id: 5104 Time: 212 Memory: 3600
*/
#include<iostream>
#include<cstdio>
using namespace std;
const int N = 100005;
int fa[N];
int find(int x){
if(x == fa[x]) return x;
return fa[x] = find(fa[x]);
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i = 1;i<=n;i++) fa[i] = i;
while(m--){
int op,u,v;
scanf("%d%d%d",&op,&u,&v);
int f1 = find(u);
int f2 = find(v);
if(op==1){
fa[f1] = f2;
}
else{
if(f1 == f2) printf("YES\n");
else printf("NO\n");
}
}
}