传送门
解析:
带权并查集裸题啊。
我们用一个
l
a
s
t
last
l
a
s
t
记录根到最远的节点的距离,合并一下就好了。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
#define _debug(x) cerr<<#x<<" : "<<x<<endl
inline
int getint(){
re int num;
re char c;
while(!isdigit(c=gc()));num=c^48;
while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
return num;
}
inline
void outint(int a){
static char ch[13];
if(a==0)pc('0');
while(a)ch[++ch[0]]=a-a/10*10,a/=10;
while(ch[0])pc(ch[ch[0]--]^48);
}
inline
char getalpha(){
re char c;
while(!isalpha(c=gc()));
return c;
}
cs int N=30002;
int fa[N],dep[N],last[N];
inline
int getfa(int x){
if(x==fa[x])return x;
int tmp=getfa(fa[x]);
dep[x]+=dep[fa[x]];
return fa[x]=tmp;
}
inline
void init(){
for(int re i=1;i<=30000;++i){
fa[i]=i;
dep[i]=0;
last[i]=1;
}
}
int T;
signed main(){
init();
T=getint();
while(T--){
char op=getalpha();
int i=getint(),j=getint();
int fi=getfa(i),fj=getfa(j);
switch(op){
case 'M':{
if(fi==fj)continue;
fa[fi]=fj;
dep[fi]=last[fj];
last[fj]=last[fj]+last[fi];
break;
}
case 'C':{
if(fi!=fj)puts("-1");
else outint(abs(dep[i]-dep[j])-1),pc('\n');
break;
}
}
}
return 0;
}
版权声明:本文为zxyoi_dreamer原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。