并查集

并查集

我们结合一个题目来彻底了解这个算法吧。
问题 A: 朋友圈

有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

我们把这个题目当成社会,不是朋友我们肯定就要打架,打完架就是朋友了。那是朋友我们肯定不要打架吧,那a和b是不是朋友??
这我怎么知道。。
所以大家就弄了个朋友圈,挑一个人做老大,老大一样我们自然是朋友
好,那我们老大不一样怎么办,我们不是朋友呗,打一架,怎么打呢??那就要老大出马,打赢了你们归我们老大管,输了我们归你们老大管,好,结束。
出代码:

#include<stdio.h>
int a[500000];
int find(int zz)
{
    int x;
    int y;
    x=zz;
    while(zz!=a[zz])//找老大
    {
        zz=a[zz];//我只认识我的上级
    }
    while(x!=zz)//这里zz为老大
    {
        y=a[x];
        a[x]=zz;
        x=y;
    }//(只是一个交换代码,不要想太多,)把所有下级归老大管,方便别人查找老大
    return zz;//把老大告诉他
}
main()
{
    int n,m,s,k,i,l,kboss,lboss;
    while(~scanf("%d%d",&n,&m))
    {
        s=n;
        for(i=1; i<=n; i++)
        {
            a[i]=i;
        }
        while(m--)
        {
            scanf("%d%d",&k,&l);
            if(k>=1&&k<=n&&l>=1&&l<=n)
            {
                kboss=find(k);//他去找自己的老大
                lboss=find(l);//他也去找自己的老大
                if(kboss!=lboss)//两个老大不一样,就是打,输了的归对手管。
                {
                    a[kboss]=lboss;//老大归我管了,其他人也只能服从我。
                    s--;//以后都是朋友,同处一个朋友圈,敌人减一;
                }
            }
        }
        printf("%d\n",s);//输出最终朋友圈
    }
}

当今社会,不服就是干。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值