7.3 并查集搜索
并查集算法
并查集算法是一个利用结点关系,进行分类合组的算法
简介
并查集可以通过一个一维数组来实现
我们把每一个点视作一个"独立的,只有一个结点"的树
之后我们可以通过一些条件,逐渐将这些树合并成一棵大树
合并的过程,其实就是找统一的父节点的过程,我们可以自定两条原则:
1.相异的情况下,把右边的父节点改为左边的父节点。视作二者合并成了一组
2.通过两者最高的父节点来进行比较
另外,既然我们通过层层推进找到了某个点的父节点,那么我们在"统一"之后,也可以顺便的把路上的其它结点修改,这样会方便我们的二次寻找
代码示例
#include <stdio.h>
int f[1001] = {0} s,n,m,sum = 0 ;
//最开始的初始化
void init()
{
int i ;
for(i=0;i<=n;i++)
f[i] = i ;//最开始的时候,每个点的最高父节点就是它自己
return ;
}
//这是找爹的递归函数,不停的寻找直到找到最高父节点为止
int getf(int v)
{
if(f[v] == v){
return ; //“集团”内只有一个人的情况
}
else
{
//路径压缩,每次在函数返回的时候,顺带把路径上的结点都修改
f[v] = getf(f[v]) ;
return f[v];
}
}
//合并两个子集的函数、
void merge(int v , int u)
{
int t1,t2 ; //t1,t2指的是两个子集的最高父节点
t1 = getf(v);
t2 = getf(u);
if(t1!=t2){
//两者不在同一集合中,才进行合并
f[t2] = t1 ; //向左合并原则
}
return ;
}
//主程序
int main()
{
int i,x,y;
scanf("%d %d",&n,&m);
init();
for(i=1;i<=m;i++)
{
scanf("%d %d",&x,&y);
merge(x,y);
}
//扫描打印结果
for(i=1;i<=n;i++)
{
if(f[i] == i )
sum++;
}
printf("%d \n",sum);
getchar();getchar()
return 0 ;
}
并查集也被称为“不相交集”数据结构