【UVA11987】Almost Union-Find
2024-10-21 09:19:22
题目就告诉我们要用并查集了,操作1和3用裸的带权并查集就行了,
操作2相当于将p结点从当前树中删除,再插入到q的树中,直接删除的话比较麻烦,不妨把它的“尸体”留在原来的地方,在q的树中插入一个新的点,维护一个指向编号为p点的指针即可
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
using namespace std;
const int MAXN=2000010;
int n,q,fa[MAXN],size[MAXN],sum[MAXN],m[MAXN],cnt;
inline int read(){
int x=0; char c=getchar();
while(c<'0') c=getchar();
while(c>='0') x=(x<<3)+(x<<1)+c-'0',c=getchar();
return x;
}
inline int find(int x){
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
int main()
{
while(scanf("%d%d",&n,&q)!=EOF){
cnt=n;
for(int i=1;i<=n;++i)
fa[i]=i,size[i]=1,sum[i]=i,m[i]=i;
int op,x,y;
while(q--){
op=read();
if(op==1){
x=read(),y=read();
x=m[x]; y=m[y];
if(find(x)==find(y)) continue;
if(rand()%2) swap(x,y);
size[find(y)]+=size[find(x)];
sum[find(y)]+=sum[find(x)];
fa[find(x)]=find(y);
}
else if(op==2){
int p=read(),q=read();
x=m[p]; y=m[q];
if(find(x)==find(y)) continue;
--size[find(x)];
++size[find(y)];
sum[find(x)]-=p;
sum[find(y)]+=p;
m[p]=++cnt;
fa[cnt]=find(y);
}
else{
x=read(); x=m[x];
printf("%d %d\n",size[find(x)],sum[find(x)]);
}
}
}
return 0;
}
最新文章
- OpenGL 学习
- Let&#39;s Encrypt这个免费的证书签发服务
- 在Android平台下的基于Linux-C 的测试程序
- Go support for Android
- CDOJ 483 Data Structure Problem DFS
- hdu 4602 Partition (概率方法)
- php中traits学习笔记
- POJ 3660	Cow Contest 弗洛伊德
- Docker 三剑客之 Docker Swarm
- [DeeplearningAI笔记]改善深层神经网络_深度学习的实用层面1.9_归一化normalization
- Redis面试点
- swiper轮播在ie浏览器上遇到的显示问题探索
- eclipse配置tomcat,让java web项目运行起来!
- 64位ubuntu搭建android开发环境问题解决方案
- linux下设置计划任务执行python脚本
- java 反射原理写了一个赋值和取值通用类
- java中常量接口及实现常量接口的利与弊
- 如何更改删除window服务?
- Inno Setup Winfrom 打包工具
- 面经问题总结——django相关