题意:有n个村庄,初始每个村庄有一个龙珠,然后T是将A中的所有龙珠转到B所在的村庄中,然后Q是问A编号的龙珠所在的位置,这个位置的龙珠数量,和A移动的次数
思路:用并查集的路径压缩来完成每个龙珠的转换次数,剩下的两个操作直接用简单的并查集即可完成,而路径压缩也就等价于这个点在走到现在位置所走的路径,那么路径压缩时直接将路过的值加起来就是结果了,画图可以很快看出来他的思想的
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
const int maxn=10010;
int f[maxn],num[maxn],time[maxn];
int find1(int x){
if(x==f[x]) return f[x];
int t=f[x];
f[x]=find1(f[x]);
time[x]+=time[t];
return f[x];
}
void unite(int a,int b){
int aa=find1(a);
int bb=find1(b);
if(aa==bb) return ;
f[aa]=bb;num[bb]+=num[aa];
time[aa]++;
}
int main(){
int T,cas=1,n,m,u,v;
char ch[10];
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++){
f[i]=i;num[i]=1;time[i]=0;
}
printf("Case %d:\n",cas++);
for(int i=0;i<m;i++){
scanf("%s",ch);
if(ch[0]=='Q'){
scanf("%d",&u);
int ans=find1(u);
printf("%d %d %d\n",ans,num[ans],time[u]);
}else if(ch[0]=='T'){
scanf("%d%d",&u,&v);
unite(u,v);
}
}
}
return 0;
}