带权并查集。
跟poj1182相比,权更新和偏移的方法要简单一些。
#include<cstdio>
struct BALL
{
int pre;
int rel;
}node[10001];
int city[10001];
void init(int n)
{
for(int i=1;i<=n;i++)
{
node[i].pre=i;
node[i].rel=0;
city[i]=1;
}
}
int find(int a)
{
if(node[a].pre!=a)
{
int temp=node[a].pre;
node[a].pre=find(node[a].pre);
node[a].rel+=node[temp].rel;
}
return node[a].pre;
}
void unin(int a,int b)
{
int ai=find(a),bi=find(b);
if(ai==bi) return;
node[ai].rel++;
node[ai].pre=bi;
city[bi]=city[ai]+city[bi];
city[ai]=0;
}
int main()
{
int t;
scanf("%d",&t);
for(int ti=1;ti<=t;ti++)
{
int n,q;
scanf("%d%d",&n,&q);
init(n);
int x[n],y[n],z[n],k=0;
while(q--)
{
char temp[2];
scanf("%s",temp);
if(temp[0]=='T')
{
int a,b;
scanf("%d%d",&a,&b);
unin(a,b);
}
else if(temp[0]=='Q')
{
int a;
scanf("%d",&a);
x[k]=find(a);
y[k]=city[x[k]];
z[k++]=node[a].rel;
}
}
printf("Case %d:\n",ti);
for(int i=0;i<k;i++)
printf("%d %d %d\n",x[i],y[i],z[i]);
}
return 0;
}