利用路径压缩来统计每个节点到树根之间路径上的一些信息(边带权)
题目链接
以前做这个题的时候,一直有一个疑问,为啥要开两个数组,一个dis[]那是应该的,为什么还得加一个Size[]数组呢,当我其他的题的发现其实一个dis[]就可以了,为啥这里不行?
这个题的特殊点就是两棵树合并的时候,x的祖先接在y的树的叶子结点。但是y所在的树,y不一定是这棵树的叶子结点,造成dis[x的祖先]更新没办法实现,所以引入了Size[],它的功能不仅知道这个棵树的结点数量,同时也代表这个树的叶子结点到根的距离,这题的特殊点,这棵树一定是一个队列,也就是线性的。
const int N=3e5+5;
int fat[N],dis[N],Size[N];
int find(int x)
{
if(fat[x]==x)
return x;
int root=find(fat[x]);
dis[x]+=dis[fat[x]];
return fat[x]=root;
}
signed main()
{
IOS;
//file();
for(int i=1;i<=3e4;i++)
fat[i]=i,dis[i]=0,Size[i]=1;
int t;
cin>>t;
while(t--)
{
char a;
int b,c;
cin>>a>>b>>c;
int tb=find(b);
int tc=find(c);
if(a=='M')
{
fat[tb]=tc;
dis[tb]+=Size[tc];
Size[tc]+=Size[tb];
}
else
cout<<(tb==tc?abs(dis[b]-dis[c])-1:-1)<<endl;
}
return 0;
}