UVA11987 Almost Union-Find
思路:
题目中与一般并查集不同的是,要把一个数从一个集合中拿出来,放到另一个集合中
如果现有两个集合 { 1 , 2 } \{1,2\} {1,2} , { 3 } ,\{3\} ,{3}
且p[1]=2
如果要把2拿出来给3
简单的p[2]=3是不行的,因为1也会受到牵连
想法:
可以给数组开
2
N
2N
2N
1
1
1~
N
N
N储存数字,
N
+
1
N+1
N+1~
2
N
2N
2N储存 减去N后的数字对应的集合
这样可以很方便地拿出单个数字放入别的集合中.原集合中的数进行find操作也不会受影响
#include<stdio.h>
#include<iostream>
#include<cstdlib>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int p[N*2];
int size[N*2];
int sum[N*2];
int find(int x)
{
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
int n,m;
int main()
{
//freopen("uva.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1;i<=n*2;i++)
{
if(i<=n)
{
p[i]=n+i;
}
else
{
p[i]=i;
sum[i]=i-n;
size[i]=1;
}
}
while(m--)
{
int op,a,b;
scanf("%d",&op);
if(op!=3)
scanf("%d%d",&a,&b);
else scanf("%d",&a);
int pa=find(a);
int pb=find(b);
if(op==1)
{
if(pa!=pb)
{
p[pa]=pb;
sum[pb]+=sum[pa];
size[pb]+=size[pa];
}
}
else if(op==2)
{
if(pa!=pb)
{
sum[pb]+=a;
size[pb]++;
p[a]=pb;
size[pa]--;
sum[pa]-=a;
}
}
else
{
printf("%d %d\n",size[pa],sum[pa]);
}
}
}
return 0;
}
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现