并查集的合并和查找

主要操作

1.合并集合 合并两个集合

2.查找集合 查找两个元素是否在一个集合中

朴素查找

int finds(int x)
{ while(x != f[x]) x = f[x];
  
  return x;
}
//举列
/* 4 != f[4]  /f[4] = 2继续查找
  
   2 != f[2]  /f[2] = 1
   
   1  = f[1]  /此时退出循环中
*/
//从中可以看出当 当这些点合并出一个长长的链条状时,如果你从最后一个元素开始查找,会从最后一个
//找到第一个,需要很长的时间。于是就有了路径压缩这一优化过程

优化查找

//路径压缩
int finds(int x)       
{   if(x != f[x]) 
   {  
     f[x] = finds(f[x]); 
   }                           
    return f[x];
}

// f[4] = 2 ,f[2] = 1, f[1] = 1;
// 当x的祖先节点不等于它本身时,进行路径优化
// 4 != f[4] 此时f[4] = 2; 
// f[4] = finds(f[4]) // 相当于finds(2) 
// 2 != f[2] 此时f[2] = 1;
// f[2] = finds(f[2]) // 相当于finds(1)
// 此时f[1] = 1 把1往回传  个人感觉就是递归的过程
此时 f[4] = f[2] = f[1] = 1;
//预处理 每一个节点都是一颗子树
for(int i = 1; i <= n; i ++) f[i] = i;

int a, b,x,y;
scanf("%d%d",&x,&y);

a = find(x); //找到x的祖宗节点
b = find(y); //找到y的祖宗节点

f[a] = b;  
//让x的祖宗节点的祖宗节点 等于y的祖宗节点
//说的有点绕口了,就是让a的祖宗节点等于b 
//如果还不理解的话,你就这样想 本来x的祖宗节点就是自身(相当于二叉树的根结点)
//现在让他不等于自身,换成另外一个节点了,这个节点是y的祖宗节点
           

题型 1.最简单的就是合并集合,查找一下两点是否在同一个集合中

        2.统计某个集合中点的个数,统计有几个集合

        3.最短生成树

题型1

题型2

题型3

感兴趣的可以去找一下蓝桥杯一道真题七数码,可以用并查集做。

题目肯定得从 普及 - 提高 - 省选 慢慢来,多做题掌握

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值