NOI2002银河英雄传

可持久化并查集 \mathbf{可持久化并查集} 可持久化并查集
题目读完显然就是并查集,但是要维护每个点到根的距离 题目读完显然就是并查集,但是要维护每个点到根的距离 题目读完显然就是并查集,但是要维护每个点到根的距离
如果不用路径压缩的话很简单,每次寻找父节点的时候把整个树的深度都更新一遍 如果不用路径压缩的话很简单,每次寻找父节点的时候把整个树的深度都更新一遍 如果不用路径压缩的话很简单,每次寻找父节点的时候把整个树的深度都更新一遍
但是要注意 M X Y 并不是把 X 接在 Y 后面,而是把 X 所在的一列整体接在 Y 一列的后面 但是要注意\mathrm{M\quad X\quad Y}并不是把\mathrm{X}接在\mathrm{Y}后面,而是把\mathrm{X}所在的一列整体接在\mathrm{Y}一列的后面 但是要注意MXY并不是把X接在Y后面,而是把X所在的一列整体接在Y一列的后面
可以注意到数据范围如果不用路径压缩会超时,显然要进行路径压缩,但是路径压缩的时候要维护节点的深度 可以注意到数据范围如果不用路径压缩会超时,显然要进行路径压缩,但是路径压缩的时候要维护节点的深度 可以注意到数据范围如果不用路径压缩会超时,显然要进行路径压缩,但是路径压缩的时候要维护节点的深度
这里使用两个数组来维护 d e e p 维护某个节点的深度, s e t t 维护某个节点所在队列的舰艇个数 这里使用两个数组来维护\mathrm{deep}维护某个节点的深度,\mathrm{sett}维护某个节点所在队列的舰艇个数 这里使用两个数组来维护deep维护某个节点的深度,sett维护某个节点所在队列的舰艇个数

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>

using namespace std;

const int MAXN = 30005;
int f[MAXN];
int deep[MAXN];
int sett[MAXN];

int getfather(int k){
	if(f[k] == k) return k;
	int p = f[k];
	f[k] = getfather(f[k]);
	deep[k] += deep[p];
	sett[k] = sett[f[k]];
	return f[k];
}

int main(){
	for(int i = 1; i <= 30000; i ++){
		f[i] = i;
		deep[i] = 0;
		sett[i] = 1;
	}
	int T;
	cin>>T;
	for(int i = 1; i <= T; i ++){
		char s;
		int x,y,fa,fb;
		cin>>s>>x>>y;
		if(s == 'M'){
			fa = getfather(x);
			fb = getfather(y);
			f[fa] = fb;
			deep[fa] += sett[fb];
			sett[fa] += sett[fb];
			sett[fb] = sett[fa];
		}
		if(s == 'C'){
			int fa = getfather(x);
			int fb = getfather(y);
			if(fa == fb) cout<<abs(deep[x] - deep[y]) - 1<<endl;
			else cout<<-1<<endl;
		}
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值