题目链接:poj1988
/*
题意:进行m次操作,
1、M x y 将包含x的集合移动到y上面
2、C x, 计算x下面有几个元素。
思路:用f[x]表示x的根结点,rank[x]表示x所在集合的元素个数,top[x]表示x上面有几个元素。
每次进行路径压缩时,top[x]都要加上top[f[x]](即加上它父亲上面的点的个数)
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
const int N = 1e5 + 10;
int f[N],rank[N],top[N];
void init(int &n)
{
for(int i = 0; i <= n; i ++)
f[i] = i, rank[i] = 1, top[i] = 0;
}
int find(int x)
{
if(x != f[x]){
int fx = f[x];
f[x] = find(f[x]);
top[x] += top[fx];//加上父亲上面的点的个数
}
return f[x];
}
void Union(int x, int y)
{
int fx = find(x);
int fy = find(y);
if(fx == fy) return;//在同一个集合内
f[fy] = fx;
top[fy] += rank[fx];
rank[fx] += rank[fy];
}
int main()
{
int T,i,j,n,m,x,y;
while(~scanf("%d",&n))
{
init(n);
while(n--){
char a[2];
scanf("%s",a);
if(a[0] == 'M'){
scanf("%d%d",&x,&y);
Union(x, y);
}
if(a[0] == 'C'){
scanf("%d",&x);
int root = find(x);
int ans = rank[root]-top[x]-1;
printf("%d\n",ans);
}
}
}
return 0;
}