并查集

并查集

并查集是由一群集合构成,最开始时所有元素各自单独构成一个集合。当集合中只有一个元素时,这个集合的代表节点即为该元素,该元素的father也是自己。当一个集合中有多个节点时,下层节点的father为上层节点,最上层节点的father指向自己,最上层的节点叫做这个集合的代表节点。
上面这些都是生硬的术语,我们直接讲一个生动形象的题目,方便理解并查集。

上面这个题目就可以用并查集做,我们可以有这样一个思路,让每个朋友圈有一个老大,如果两个朋友关系的人的老大不一样,那么就在两个老大中选一个新老大,最后只需要统计老大的个数,不就是朋友圈的个数了吗。思路有了,我们直接上代码:

#include<stdio.h>
int a[110000];
int hhh1(int x)//找老大函数
{
if(x==a[x])
return a[x];//自己就是朋友圈的老大
else
{
a[x]=hhh1(a[x]);//找自己朋友圈的老大
return a[x];
}
}
void hhh2(int x,int y)//x和y是同一个朋友圈的
{
int s=hhh1(x);//找x的老大
int t=hhh1(y);//找y的老大
if(s!=t)
a[s]=t;//如果两个老大不同,则两个老大可以通过x和y认识,新老大就是两个老大中的随便一个
}
int main()
{
int i,j,n,m,ans=0,x,y;//ans统计朋友圈个数
scanf("%d %d",&n,&m);
for(i=1; i<=n; i++)
a[i]=i;//一开始各自的老大都是自己
for(j=1; j<=m; j++)
{
scanf("%d %d",&x,&y);
hhh2(x,y);//两个朋友朋友圈的融合,产生一个新老大
}
for(i=1; i<=n; i++)
if(a[i]==i)//统计有几个老大,相应的就有几个朋友圈
ans++;
printf("%d",ans);
return 0;
}
通过注释应该能很好的理解思路了吧,希望对你理解并查集有所帮助。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值