并查集

  1. 并查集算法(union_find sets)不支持分割一个集合,求连通子图、求最小生成树
  2. 并查集由pre[]数组和两个函数find(),join()组成,find()是寻找根节点,join()是连接两个根节点,合并路线的。
  3. 模板:

初始化,建立子树

我们将每一个结点的前导结点设置为自己,如果在join函数时未能形成连通,将独立成点。

for(int i=0;i<1000;++i)
{
	pre[i]=i;           //初始化,建立各个孤立的子树 
}

find()函数

int pre[1000];
//记得初始化

int find(int x)        //寻找x的根节点 
{
	int r=x;
	while(pre[r]!=r){    //r不是根节点,就继续以r往上找 
		r=pre[r];
	}
	int i=x,j;
	while(pre[i]!=r)     //路径压缩 
	{
		j=pre[i];        //j暂时储存i的父节点 
		pre[i]=r;        //更新i的父节点 
		i=j; 
	} 
	return r;            //返回根节点 
}

递归:

int find(int x)
{
	if(pre[x]!=x)
	{
		pre[x] = find(pre[x]);
	}
	return pre[x];
}

路径压缩为了加快查找的速度,将x点与其根节点直接相连,构造成类似于只有叶子结点而没有分支结点的树

这里需要注意带权值的并查集,循环和递归有很大区别(递归数据更新从根结点开始向下更新,而循环是从子节点一直向上更新),建议用递归。

join()函数

void join(int x,int y)
{
	int fx=find(x),fy=find(y);
	if(fx!=fy)
	{
		pre[fx]=fy;      //将x,y连起来,两个子树的根节点谁做根节点无关紧要 
	}
}

这里是一篇有意思的博客:https://blog.csdn.net/the_best_man/article/details/62416938

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值