2018.09.27【NOI2002】【洛谷P1196】银河英雄传说(带权并查集)

  • Post author:
  • Post category:其他





传送门




解析:

带权并查集裸题啊。

我们用一个



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 版权协议,转载请附上原文出处链接和本声明。