HDU1213 & 并查集的一些学习笔记
来源:互联网 发布:java web快速开发 ide 编辑:程序博客网 时间:2024/05/16 15:08
关于并查集我不是直接接触的,而是通过克鲁斯卡尔算法粗略地学习的……挺惭愧……这里我推荐一个我入门时候看到的博客http://blog.csdn.net/dellaserss/article/details/7724401/点击打开链接
主体结构就是一个一维数组而已,我习惯用pre,数组中的内容是记录每一个点的父亲节点在哪里。
比如,下标为2的元素是4(pre[2]==4),就说明序号为2的点的父亲节点的序号是4.
并查集所要维护的东西是树。
并查集的主要函数有:Find函数,作用是找到这个点的祖宗节点;unite函数,作用是连接两个点所在的树;init函数,初始化pre函数(这个初始化是必要的)。
作为初学者,我对unite函数是有一些讨论的,也就是对合并的方式有所注意,因为有很多种树的合并方式。
一开始unite我写的是这样子:
void unite(int a,int b){ int x=Find(a); int y=Find(b); if(x!=y) pre[x]=y;}
而Find函数就是很朴素的找祖宗
int Find(int x){ int r=x; while(r!=pre[r]) r=pre[r]; return r;}
并没有做路径的压缩。
在这里我想提一点,如果不是以一定的大小顺序输入相连数据的话,pre[x]=y和pre[y]=x没有很大的实质性的差别,因为谁也不知道x和y谁大,所以当Find函数没有路径压缩时,这两种写法无所谓。
另外一点就是当一个点的父亲节点就是他自己时,这个点就是这棵树的根节点(祖宗节点)。(即pre[r]==r的时候)
我们发现,unite这个函数只是把一棵树A的祖宗节点连到了另一个树B的祖宗节点上,而并没有把A的所有的子节点都直接连到B树的祖宗节点上,这样在寻找A树叶子的祖宗节点时会浪费不少的时间,因为要一个父亲节点一个父亲节点地去找。
我们何不直接把A的所有子节点都直接连到B树的祖宗节点上来呢?(也就是路径压缩)
因为最终是求森林中有几棵树,所以进行上面的操作和最终结果没有差别,而且还能省时间。
要怎么做呢?
在Find函数这里做手脚。
这个Find函数可以进行路径压缩的优化的。
int Find(int x){ if(pre[x]!=x) pre[x]=Find(pre[x]); else return pre[x];}
我开始不怎么理解,我们可以先把pre[x]=Find(pre[x])中的前面的pre[x]=去掉,这样只要pre[x]!=x那么Find函数会一直找下去,找到根,带着根的值return,这时我们把pre[x]加上去。那么这个函数就顺带着把x的所有的父节点的父节点都变成了根,也就完成了路径压缩的任务。(注意路劲压缩不是在两棵树合并时候进行的,而是在同一棵树上找根时候进行的。)
具体的题目有很多就举一个例子好了HDU 1213,毕竟是并查集裸题。
AC代码:
#include <iostream>#include <cstdio>#include <string>#include <cstring>using namespace std;const int maxn=1e3+10;int N,M;int pre[maxn];void init(){ for(int i=1;i<=N;i++) pre[i]=i;}int Find(int x){ if(pre[x]!=x) pre[x]=Find(pre[x]); else return pre[x];}void unite(int a,int b){ int x=Find(a); int y=Find(b); pre[y]=x;}int main(){ int T; scanf("%d",&T); while(T--) { int t1,t2; scanf("%d%d",&N,&M); init(); for(int i=1;i<=M;i++) { scanf("%d%d",&t1,&t2); unite(t1,t2); } int ans=0; for(int i=1;i<=N;i++) if(i==pre[i]) ans++; printf("%d\n",ans); }}
- HDU1213 & 并查集的一些学习笔记
- hdu1213 并查集
- HDU1213并查集
- HDU1213 并查集
- HDU1213(并查集)
- 并查集-hdu1213
- hdu1213 并查集
- hdu1213并查集模板
- hdu1213(并查集)
- hdu1213(并查集复习)
- hdu1213(并查集模板)
- HDU1213并查集基础
- HDU1213 基础并查集
- HDU1213基础并查集
- HDU1213 并查集模板
- hdu1213(基础并查集)
- HDU1213基础并查集
- HDU1213 How Many Tables(简单的并查集)
- [2]React 深入浅出-----React的一个高级表格实现功能
- linux下的Sort命令
- 每日一题(27)—— define定义一个宏表明1年中有多少秒
- Latex标题页的上标和脚注
- Jenkins部署到远程服务器
- HDU1213 & 并查集的一些学习笔记
- 经验分享之数据库优化
- 我印象中的指针与数组4
- spring实战-注解装配bean
- java面试题,各大企业常见的java笔试题之六
- (noip 模拟 gift)<丧病背包>
- MySQL游标使用
- MySQL的B+索引和Hash索引的区别
- pcap文件格式解析