题意:有n个球在n个城市,刚开始,1号球在1号城市,依次2号球在2号城市。
有两种操作,T A B 将A球所在城市的球全部移到B球所在城市。
Q A 查询A所在的城市,A求移动的次数,A所在城市的球的总数。
并查集主要是路径压缩时,更改 移动的次数。如 子节点的移动次数等于加等于父节点的次数
#include<cstdio>
#include<cstring>
#include<queue>
#include<iostream>
using namespace std;
#define FF freopen("Input.txt","r",stdin)
#define mem(x,y) memset(x,y,sizeof(x))
struct Node
{
int father;//根节点
int num;//球的个数
int tranport;//转移次数
}p[10200];
void init(int n)
{
for(int i=0;i<=n;i++)
{
p[i].father=i;
p[i].tranport=0;
p[i].num=1;
}
}
int find(int x)
{
int tmp=p[x].father;
if(x!=p[x].father)
p[x].father=find(tmp);
p[x].tranport+=p[tmp].tranport;//路径压缩时改变
return p[x].father; //每个球的移动次数.
}
void Union(int x,int y)
{
x=find(x);
y=find(y);
if(x==y) return ;
p[x].father=y;
p[y].num+=p[x].num;
p[x].tranport++;
p[x].num=0;
}
int main()
{
//FF;
int ncase,n,m,t=1,i,j;
char str[5];
scanf("%d",&ncase);
while(ncase--)
{
scanf("%d%d",&n,&m);
init(n);
printf("Case %d:\n",t++);
while(m--)
{
scanf("%s",str);
if(str[0]=='T')
{
scanf("%d%d",&i,&j);
Union(i,j);
}
else
{
scanf("%d",&j);
i=find(j);
printf("%d %d %d\n",i,p[i].num,p[j].tranport);
}
}
}
return 0;
}