P1196 [NOI2002]银河英雄传说 题解

Link

P1196 [NOI2002]银河英雄传说

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;
}
原文地址:https://www.cnblogs.com/martian148/p/13876845.html