Link
Solve
带权并查集,维护一个(d[i])表示和(fa[i])的距离,(size[i])表示这个子树的大小。
Code
#include<bits/stdc++.h>
using namespace std;
int T,N,d[30005],size[30005],fa[30005];
inline int read(){
int ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
inline char read_ch(){
char ch;
while(ch!='M'&&ch!='C')ch=getchar();
return ch;
}
int get(int x){
if(x==fa[x])return x;
int rt=get(fa[x]);
d[x]+=d[fa[x]];
return fa[x]=rt;
}
void merge(int x,int y){
int fx=get(x),fy=get(y);
if(fx==fy)return ;
fa[fx]=fy;
d[fx]=size[fy];
size[fy]+=size[fx];
}
int query(int x,int y){
int fx=get(x),fy=get(y);
if(fx!=fy)return -1;
return abs(d[x]-d[y])-1;
}
int main(){
T=read();
for(int i=1;i<=30000;i++)fa[i]=i,size[i]=1;
for(int i=1;i<=T;i++){
char ch=read_ch();
int now_x=read(),now_y=read();
if(ch=='M')merge(now_x,now_y);
else printf("%d
",query(now_x,now_y));
}
return 0;
}
另一种写法
#include<bits/stdc++.h>
using namespace std;
int T,N,d[30005],size[30005],fa[30005];
inline int read(){
int ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
inline char read_ch(){
char ch;
while(ch!='M'&&ch!='C')ch=getchar();
return ch;
}
int get(int x){
if(x==fa[x])return x;
int k=fa[x];
fa[x]=get(fa[x]);
d[x]+=d[k];
size[x]=size[fa[x]];
return fa[x];
}
void merge(int x,int y){
int fx=get(x),fy=get(y);
if(fx==fy)return ;
fa[fx]=fy;
d[fx]+=size[fy];
size[fx]+=size[fy];
size[fy]=size[fx];
}
int query(int x,int y){
int fx=get(x),fy=get(y);
if(fx!=fy)return -1;
return abs(d[x]-d[y])-1;
}
int main(){
freopen("P1196.in","r",stdin);
freopen("P1196.out","w",stdout);
T=read();
for(int i=1;i<=30000;i++)fa[i]=i,size[i]=1;
for(int i=1;i<=T;i++){
char ch=read_ch();
int now_x=read(),now_y=read();
// cin>>ch>>now_x>>now_y;
if(ch=='M')merge(now_x,now_y);
else printf("%d
",query(now_x,now_y));
}
return 0;
}