并查集
并查集是一种树型的数据结构,用于处理一些不相关集合的合并及查询问题,是解决动态连通性问题的一类非常高效的数据结构。
实现方法
1.初始化:把每个点所在集合初始化为其自身;
void f()
{
for(int i=1;i<=n;i++)
x[i]=i;
}
2.合并:将两个元素所在的集合合并为一个集合;
void hb(int x,int y)
{
int t1=find(x);
int t2=find(y);
if(t1!=t2)
x[t2]=t1;
}
3.查找:查找元素所在的集合即根节点;
int find(int n) //循环查找
{
while(x[i]!=n)
n=x[n];
return n;
}
int find(int n) //递归查找
{
if(n==x[n])
return x[n];
else
return find(x[n]);
}
例题
描述 有n个人,编号1-n。 现在有一个舞会,在舞会上,大家会相互介绍自己的朋友。 即:
如果a认识b,b认识c。那么在舞会上,a就会通过b认识到c。
现在,给出m个关系 每个关系描述: a b 表示编号为a和编号为b的人是朋友关系。
输入格式
输入 n和m 接下来m行,每行为a b
输出格式
最后问,会有多少个朋友圈。
输入
5 3
1 2
2 3
4 5
输出
2
完整代码
#include<stdio.h>
int f[100000];
int x(int n) //递归查找
{
if(f[n]==n)
return n;
else
{
f[n]=x(f[n]); //进行路径压缩,可以拿例子演练
return f[n];
}
}
int main()
{
int n,m,i,a,b,sum=0;
scanf("%d%d",&n,&m);
for(i=1; i<=n; i++) //初始化
f[i]=i;
for(i=0; i<m; i++)
{
scanf("%d%d",&a,&b);
int t1=x(a); //合并
int t2=x(b);
if(t1!=t2) //判断两个节点是否在一个集合中
f[t2]=t1; //我习惯把右边的集合作为左边集合的子集合,相反也没事
}
for(i=1; i<=n; i++) //最后还有几个集合
if(f[i]==i)
sum++;
printf("%d\n",sum);
return 0;
}