并查集(C语言)

@TOC
五一去重庆也回来了,说实话也该收收心开始学习了,马上一堆考试就要来了,想想就挺头大的。今天刚刚赶路回来,就写写简单的吧,过后一阵估计写博客也慢下来了,一是还是以学业为重,二是也不太想每天记挂博客这件事。
话不多说,今天学并查集。
并查集就是简单说,由一些直接的信息(每两个人的联系)来推出团伙(也就是根节点)个数。

有n个人,编号1-n。现在有一个舞会,在舞会上,大家会相互介绍自己的朋友。即: 如果a认识b,b认识c。那么在舞会上,a就会通过b认识到c。现在,给出m个关系,每个关系描述:a b 表示 编号为a和编号为b的人是朋友关系。
最后问,会有多少个朋友圈。

#include<stdio.h>
int c[100005]={0};
int get(int root)//找同一个根节点
{
    if(c[root]==root)//表示已找到
        return root;
    else
    {
        c[root]=get(c[root]);//递归,直到找到为止
        return c[root];
    }
}
void join(int a,int b)
{
    int t1,t2;//分别为两人的根节点
    t1=get(a);
    t2=get(b);
    if(t1!=t2)//判断这两个根节点是否在同一朋友圈
    {
        c[t2]=t1;
    }
    return;
}
int main()
{
    int n,m,i,a,b,sum;
    while(~scanf("%d%d",&n,&m))//n为人数,m为关系
    {
        sum=0;
        for(i=1;i<=n;i++)//初始化关系,每个人都只认识自己
            c[i]=i;
        while(m--)
        {
            scanf("%d%d",&a,&b);
            join(a,b);//开始把人群分类
        }
        for(i=1;i<=n;i++)
        {
            if(c[i]==i)//找到根节点(领袖)(只认识自己的)
                sum++;
        }
        printf("%d\n",sum);
    }
    return 0;
}

测试:
(5个人7个关系)5

点赞

发表评论

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像