并查集的题。题意是悟空去收集龙珠,一开始告诉你有t颗龙珠和信息与问题的总数q
然后是q个信息或问题
T A B就是把龙珠A所在的城市中所有龙珠送去B龙珠所在的城市
Q A就是问A龙珠所在的城市地址,该城市的龙珠个数,A龙珠的转移个数

思路:开一个结构体数组,元素代表龙珠,每颗龙珠有两个变量,一个是龙珠的前一颗龙珠的id
一个是所在城市的龙珠个数。
明显,被转移出来的龙珠是不可能回到原来的城市了,相当于该城市的龙珠被转移
这个城市就消失,可以看出,这就是并查集嘛~~!
当龙珠的id或龙珠的最终前驱的id等于城市的id时,就可以得知城市的id;
城市中有多少个龙珠可以再合并时,利用bin[fb].y+=bin[fa].y求出;
至于移动的次数,一开始我是在合并时求的,这是错的,因为没有考虑到当龙珠有后继时,会出
现后继没累加的情况,wa到我吐血!
后来直接在输出答案前,利用不断访问前驱的,求前驱的个数,就是移动的个数了,不过牺牲了时间
345ms 代码如下

 

#include<iostream>
typedef struct ball{
int x;
int y;
}ball;
ball bin[10002];
int merge(int a,int b)
{
int fa,fb;
for(fb=b;bin[fb].x!=fb;fb=bin[fb].x);
for(fa=a;bin[fa].x!=fa;fa=bin[fa].x);
if(fa==fb) return 0;
bin[fa].x=bin[fb].x;
bin[fb].y+=bin[fa].y;
return 0;
}
int main(){
int i,c,a,b,t,q,ans;
int n,m=0;
scanf("%d",&n);
while(n--)
{
m++;
scanf("%d %d",&t,&q);
printf("Case %d:\n",m);
for(i=1;i<=t;i++)
{
bin[i].x=i;
bin[i].y=1;
}
for(i=0;i<q;i++)
{
getchar();
c=getchar();
if(c=='T')
{
scanf("%d %d",&a,&b);
merge(a,b);
}
else
{
int z=0;
scanf("%d",&a);
for(ans=a;bin[ans].x!=ans;ans=bin[ans].x)
{
z++;
}
printf("%d %d %d\n",bin[ans].x,bin[ans].y,z);
}
}
}
return 0;
}