并查集

并查集

我们来通过一个例题来学习这个有趣且不是很难得算法:
在这里插入图片描述
看看题目:
为什么是两个朋友圈呢?
1和2是朋友,然后2和3又是朋友,所以1,2,3三个人互为朋友关系,然后4和5是朋友,且4和5均与1,2,3没有关系,所以就有两个朋友圈,分别是1,2,3和4,5;
好,现在题目理解了,怎么用代码来解决这个问题呢?
这里我们就要用到并查集了;
并查集
通过一个一维数组来实现,就好比这题来讲,一开始,每个人都是只有自己一个人的,后来慢慢互相交朋友,在每次判断两个人是否构成一个朋友圈时,还要注意找到他们得共同朋友。
话不多说,看代码:

#include<stdio.h>
int h[100000]={0};
int find(int p)//通过这个递归函数来找到自己所属的那个朋友圈,也就是找到此朋友圈里最早的一个朋友
{
    if(h[p]==p)
        return p;
    else//这里是路径压缩,函数返回的时候,把我的新朋友改为最后找到的最早的朋友的编号
    {
        h[p]=find(h[p]);//这里进行了路径压缩
        return h[p];
    }
}
void father(int x,int y)//这是合并两个朋友的函数
{
   int x1,y1;//x1,y1分别为x和y的朋友
   x1=find(x);
   y1=find(y);
   if(x1!=y1)//判断他们是否属于同一个朋友圈
        h[y1]=x1;
   return;
}
int main()//代码从主函数开始看比较容易理解
{
    int n,m;
    scanf("%d%d",&n,&m);
    int sum=0;
    for(int i=1;i<=n;i++)
        h[i]=i;//初始化数组,数组里面存自己的下标,表示一开始只有自己,没有朋友
    int a,b;
    for(int j=1;j<=m;j++)
    {
        scanf("%d%d",&a,&b);
        father(a,b);//开始找到自己的朋友圈
    }
    for(int k=1;k<=n;k++)//最后遍历,找出有多少个朋友圈
    {
        if(h[k]==k)
            sum++;
    }
    printf("%d",sum);
}

以上就是我对并查集的理解。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值