union find 算法 可用在聚类

本文介绍了并查集(Union Find)算法在解决聚类问题上的应用,通过四个具体的题目来阐述如何使用并查集进行集合的合并与查找。包括找到与0号有关联的所有集合人数、计算可能的宗教分支数量、判断有向关系是否能构成树以及模拟计算机网络修复等场景。并展示了不同题目中并查集操作的细微变化。
摘要由CSDN通过智能技术生成
 
并查集(Union-Find Sets)
2009-02-23 12:38

本文通过几道题介绍一下并查集的应用。

第一道题目: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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值