2020.1.23每日一题“并查集”

关于并查集

并查集就是将有关系的一些元素放在一个集合里

为他们搭建某种关系

能通过其中一个元素便得到与他有关的其他元素

如何搭建关系

要实现可追溯性,我们可以利用数组下标

规定一个root(头元素),root[root]=root

而与其有关的下一个元素比如a,root[a]=root。

以此类推root[b]=a。

路径优化

当有关系的元素很多的时候,我们关联至最后一个元素时已经递推了很多层了,为了下一次用的时候不再浪费时间,我们将他直接连至头元素上,即改变他的上层。

while(i!=root)//进行路径优化
    {
        j=per[i];//保存上一层
        per[i]=root;
        i=j;//当前层赋为上一层
    }

具体应用

数数有几个朋友圈:

有n个人,编号1-n。

现在有一个舞会,在舞会上,大家会相互介绍自己的朋友。

即: 如果a认识b,b认识c。那么在舞会上,a就会通过b认识到c。

现在,给出m个关系

每个关系描述:

a b

表示 编号为a和编号为b的人是朋友关系。

代码实现:

#include<stdio.h>
int per[202020];
int findfriend(int x)
{
    int root=x;
    while (root!=per[root])
        root=per[root];
    int i=x,j;
    while(i!=root)//进行路径优化
    {
        j=per[i];//保存上一层
        per[i]=root;
        i=j;//当前层赋为上一层
    }
    return root;
}
int main()
{
    int n,m,i,a,b,r,t;
    while(~scanf("%d%d",&n,&m))
    {
        for(i=1; i<=n; i++)
            per[i]=i;
        while(m--)
        {
            scanf("%d%d",&a,&b);
            r=findfriend(a);
            t=findfriend(b);
            if(r!=t)
            {
                    per[r]=t;
            }
        }
        int ans=0;
        for(i=1; i<=n; i++)
            if(per[i]==i)
                ans++;
        printf("%d\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值