本文通过几道题介绍一下并查集的应用。
第一道题目:The Sus pects (http://acm.pku.edu.cn/JudgeOnline/problem?id=1611)
1. N个人编号,从0到N-1。
2. 给出这N个人分成M个集合的描述(同一个人可以加入不同的集合)。
求所有和0号有关系的集合的人数!
//用到并查集的3种基本操作
//并查集虽然用线性的数组,但是使用树 的操作。
#include <stdio.h>
int set[30001],i,j;
void MakeSet(int n)
//集合初始化为-1
//set[x]<0 表示x是根 并且它的所有结点的个数为该值的绝对值。
//初始可以看成,数组中每个元素是一个根,相互独立的集合。
{
for(i=0;i<n;i++)
set[i]=-1;
}
int FindSet(int a)
//查找含有a的集合的根
{
int i=a,t;
while(set[i]>=0) //递归查找直到找到根为止
i=set[i];
while(i!=a) //压缩路径,使得各个孩子直接指向根,以便下次搜索加速。
{
t=set[a];
set[a]=i;
a=t;
}
return i;
}
int UnionSet(int a,int b)
//合并含有a和b的集合。并返回合并后树的根
{
if(a==b)
return a;
if(set[a]>=set[b])
{
set[b]+=set[a]; //把2集合元素个数相加
set[a]=b; //把a的根设置为b
return b;
}
else
{
set[a]+=set[b]; //把2集合元素个数相加
set[b]=a; //把b的根设置为a
return a;
}
}
int main()
{
int number,a,b,n,m;
while(scanf("%d %d",&n,&m) && (n || m))
{
MakeSet(n);
for(i=0;i<m;i++)
{
scanf("%d",&number);
scanf("%d",&a);
a=FindSet(a); //找到第一个元素所在集合的根。
for(j=1;j<number;j++)
{
scanf("%d",&b);
b=FindS
union find 算法 可用在聚类
最新推荐文章于 2022-06-01 10:57:36 发布
本文介绍了并查集(Union Find)算法在解决聚类问题上的应用,通过四个具体的题目来阐述如何使用并查集进行集合的合并与查找。包括找到与0号有关联的所有集合人数、计算可能的宗教分支数量、判断有向关系是否能构成树以及模拟计算机网络修复等场景。并展示了不同题目中并查集操作的细微变化。
摘要由CSDN通过智能技术生成
并查集(Union-Find Sets)
2009-02-23 12:38