1.定义
一种树形的数据结构,用于处理一些不想交集合的合并问题。
2.查找
(1)初始化
|
对于查找操作,假设需要确定x所在的集合,也就是确定集合的父结点。可以沿着parent [ x ]不断在树形结构上移动,直到到达根结点。对于每一个元素parent [ x ] 指向x在树形结构上的父节点。如果x是根结点,则令parent [ x ]=x; |
#define max 1e+10
int parent[max]; //也可以是是parent[max]
int rank[max]; //深度(层次),通常初始化为0*可要可不要*
for(int i=0;i<n;i++)
{
parent[i]=i;
rank[i]=0;
}
(2)查找函数
|
如果的 序列的parent等于他的下标,那么自然返回自身编号;如果不同(即经过了合并操作后指针指向了源头),那么就可以调用递归函数。 |
int find(int num)
{
if(parent[num]==num) //如果它是属于这个父结点下面的就返回这个数的下标,否则继续寻找
return parent[num];
return find(parent[num]);
}
(3)合并函数
|
假设需要合并两个数组元素分别为 x 和 y ,则只需要令parent [ x ]=y, 或者parent [ y ]= x; 为了使合并后的树不产生退化,即使树中左右子树的深度差尽可能小,对于每一个元素 x ,维护rank[x]为以 x 为根的子树的深度,合并时 若 rank[x]< rank[y],则令 parent[x]=y;否则parent[y]=x; |
void union(int x,int y)
{
int i=find(x);
int j=find(y);
if(i==j)
return ;
if(rank[i]>rank[j])
parent[j]=i;
else
{
if(rank[i]==rank[j])
rank[j]++;
parent[i]=j;
}
}
统计最后有多少个不相交的集合
int count=0;
//即计算有多少个parent[num]=num;
【模板】并查集
题目描述
如题,现在有一个并查集,你需要完成合并和查询操作。
输入格式
第一行包含两个整数 N,M ,表示共有 N 个元素和 M个操作。
接下来 M 行,每行包含三个整数 Zi, Xi, Yi 。
当 Zi=1 时,将 Xi 与 Yi 所在的集合合并。
当 Zi=2 时,输出 Xi 与 Yi 是否在同一集合内,是的输出Y ;否则输出 N 。
输出格式
对于每一个 Zi=2 的操作,都有一行输出,每行包含一个大写字母,为 Y 或者 N 。
样例输入 #1
4 7
2 1 2
1 1 2
2 1 2
1 3 4
2 1 4
1 2 3
2 1 4
样例输出 #1
N
Y
N
Y
提示
对于 30% 的数据,N<= 10,M<= 20。
对于 70% 的数据,N<=100,M<=10^3。
对于 100% 的数据,1<=N <=10^4,
1<=M<=2*10^5,1<= Xi, Yi<=N,Zi ∈ { 1, 2 }。
#include<stdio.h>
int tree[100000];
int n,m,x,y,z;
int fun(int num)
{
if(tree[num]==num)
return num;
return tree[num]=fun(tree[num]);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
tree[i]=i; //初始化
for(int i=0; i<m; i++)
{
scanf("%d%d%d",&z,&x,&y);
if(z==1)
tree[fun(x)]=fun(y); //合并
else
{
if(fun(x)==fun(y)) //查找
printf("Y\n");
else printf("N\n");
}
}
return 0;
}
并查集是一种用于处理不相交集合合并问题的树形数据结构。查找操作通过沿着parent数组找到集合的根结点,合并操作则通过调整parent数组避免树的退化,保持平衡。文章提供了查找和合并函数的实现,并给出了一组样例输入和输出,展示了如何使用并查集解决实际问题。

1533

被折叠的 条评论
为什么被折叠?



