做了好多基础的并查集,理解的越来越深了
这个题包含了一些并查集的基本特点
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N= 10010;
int root[N];
int rank[N];//记录每个集合的个数
int num[N];//记录转移次数,类似于树的高度
void init(int n)
{
for(int i=0;i<=n;i++)
{
root[i]=i;
rank[i]=1;
num[i]=0;
}
}
int find(int x)
{
if(x==root[x])
return x;
int temp=root[x];
root[x]=find(root[x]);
num[x]+=num[temp];//回溯,由根节点开始向下加
return root[x];
}
void Merge(int a,int b)
{
int x=find(a);
int y=find(b);
if(x!=y)
{
rank[x]+=rank[y];//集合合并在一起,被合并的就不是根节点了
rank[y]=0;
num[y]=1;
root[y]=x;
}
}
int main()
{
int T;
cin>>T;
for(int kase=1;kase<=T;kase++)
{
int n,m,x,y;
char ch[2];
cin>>n>>m;
init(n);
printf("Case %d:\n",kase);
for(int i=0;i<m;i++)
{
scanf(" %s%d",ch,&x);
if(ch[0]=='T')
{
scanf("%d",&y);
Merge(y,x);
}
if(ch[0]=='Q')
{
int t=find(x);
printf("%d %d %d\n",t,rank[t],num[x]);
}
}
}
return 0;
}