这个与 More is better 都是并查集
li[i]表示 i 龙珠所在城市
city[i]表示i城市有几个龙珠
for(int i=0;i<=n;i++)
{
li[i]=i;
city[i]=1;
}
'T’时
先找a龙珠所在城市x,将所有龙珠转移至b所在城市y
再进行合并,这里没有路径压缩(More is better需要,不然超时,这道题不压缩我觉得更好理解)
因为这颗树的层数就代表转移次数
scanf("%d%d",&a,&b);
int x=f(a),y=f(b);
city[y]+=city[x];
city[x]=0;
if(x!=y)
{
li[x]=y;
}
'Q‘时
scanf("%d",&a);
int h=chan(a);
printf("%d %d %d\n",h,city[h],cnt);
cnt=0;
找到a所在城市h city[h]是其中龙珠数量;cnt是进行查询操作时的计数器,因为chan 函数中循环次数就是a的层数,及转移次数
int chan(int i)
{
int t=i;
while (t!=li[t])
{
t=li[t];
cnt++;
}
return t;
}
完整代码
#include<bits/stdc++.h>
using namespace std;
int li[10005];
int t,a,b,n,q,cnt;
char c;
int f(int i)
{
int t=i;
while (t!=li[t])
{
t=li[t];
cnt++;
}
return t;
}
int chan(int i)
{
int t=i;
while (t!=li[t])
{
t=li[t];
cnt++;
}
return t;
}
int main()
{
// freopen("C:\\Users\\Lenovo\\Desktop\\input.txt","r",stdin);
scanf("%d",&t);
for(int l=0;l<t;l++)
{
printf("Case %d:\n",l+1);
int city[10005]={0};
scanf("%d%d",&n,&q);
for(int i=0;i<=n;i++)
{
li[i]=i;
city[i]=1;
}
for(int i=0;i<q;i++)
{
getchar();scanf("%c",&c);
if(c=='T')
{
scanf("%d%d",&a,&b);
int x=f(a),y=f(b);
city[y]+=city[x];
city[x]=0;
if(x!=y)
{
li[x]=y;
}
}
else
{
scanf("%d",&a);
int h=chan(a);
printf("%d %d %d\n",h,city[h],cnt);
cnt=0;
}
}
}
return 0;
}