C++学习第二篇——并查集

并查集模板:(仅供参考模板没有过于详细的讲解)
附加ACM超时原因,printf输出,elseif判断,以及scanf同时输入
第一步,初始化数组,将数组的值赋值为下标。

int arr[1005];
void init()
{
	for(int i=0;i<1005;i++)
	{
		arr[i]=i;
	}
}

第二步,并查集的主要两个函数Union和find。
find函数是通过递归进行调用,找到当前点的老大,也就是集合的顶点,这个点会是这个集合中任意的一个数字。
Union函数是连接两个点的函数,通过调用find函数找到两个点的分属集合的顶点,将一个顶点数组的值赋值为另一个的顶点,使其变成一个集合,一个顶点。

int find(int a)
{
	if(arr[a]!=a) 
	{
		arr[a]=find(arr[a]);//注意这一步很关键,为了压缩后面搜索的时间,减少时间复杂度
	}
	return arr[a];
}
void Union(int a,int b)
{
	int f1=find(a);
	int f2=find(b);
	if(f1!=f2)
	{
		arr[f1]=f2;
	}
}

第三步,将两个点通过Union函数连接。
判断集合数的方法:

int count=0;
for(int i=1;i<=n;i++)
{
	if(arr[i]==i) count++;
}

注意:要从1开始,因为0没有算进端点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值