并查集专题学习
来源:互联网 发布:网络语言橘子什么意思 编辑:程序博客网 时间:2024/05/21 16:53
在一些应用问题中,需要将n个不同的元素划分成一组不相交的集合。开始时,每个元素自成一个单元素集合,然后按一定顺序将属于同一组元素的集合合并。其间要反复用到查询某个元素属于哪个集合的运算。适合于描述这类问题的抽象数据类型称为并查集。——摘自《算法设计与分析》(王晓东)
一、数据操作
它常是一种树形结构,一般有两种操作:
合并两个不相交集合
判断两个元素是否属于同一集合
这么说有点抽象,我们看一下图(需要注意的是,一开始我们假设元素都是分别属于一个独立的集合里的):
(1) 合并两个不相交集合 操作很简单:先设置一个数组Father[x],表示x的“父亲”的编号。 那么,合并两个不相交集合的方法就是,找到其中一个集合最父亲的父亲(也就是最久远的祖先),将另外一个集合的最久远的祖先的父亲指向它。
inline void union(int x, int y){ // get_father 是下面将讲到的操作 father[get_father(x)]= get_father(y); //指向最祖先的祖先}
(2) 判断两个元素是否属于同一集合 仍然使用上面的数组。则本操作即可转换为寻找两个元素的最久远祖先是否相同。可以采用递归实现。
inline char is_same(int x, int y){ return get_father(x) == get_father(y);}
二、算法优化
但是需要注意的是,并查集我们常看到的是一种路径压缩后的并查集。
(1)路径压缩
刚才我们说过,寻找祖先时采用递归,但是一旦元素一多起来,或退化成一条链,每次GetFather都将会使用O(n)的复杂度,这显然不是我们想要的。
对此,我们必须要进行路径压缩,即我们找到最久远的祖先时“顺便”把它的子孙直接连接到它上面。这就是路径压缩了。使用路径压缩的代码如下,时间复杂度基本可以认为是常数的。
void init(void){ int i; for (i=0; i<MAX; i++) father[i] = i;}int get_father(int v){ if (father[v] != v) father[v] = get_father(father[v]); return father[v];}
(2)rank合并
合并时将元素少的集合合并到元素多的集合中。
// 初始化static int rank[MAX] = { 0 }; char judge(int x, int y){ int fx, fy; if ((fx = get_father(x)) == (fy = get_father(y))) return 1; if (rank[fx] > rank[fy]) father[fy] = fx; else { father[fx] = fy; if (rank[fx] == rank[fy]) rank[fy]++; } return 0;}
三、时间复杂度
O(n*α(n))
其中α(x),对于x=宇宙中原子数之和,α(x)不大于4
事实上,路经压缩后的并查集的复杂度是一个很小的常数。
四、例题及其源代码(对不住,本人小菜,只能选些标准题)
1.HDU 1213 简单并查集
原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=1213
本人解题报告:http://blog.csdn.net/fsafs168/article/details/7801042
2.HDU 1232 中下并查集
原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=1232
本人解题报告:http://blog.csdn.net/fsafs168/article/details/7801090
3.HDU 1863 中等并查集
原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=18634.HDU 1875 中等并查集
原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=1875- 并查集专题学习
- 并查集专题
- 【并查集专题】
- 并查集专题
- 并查集专题【完结】
- 【并查集专题】【HDU】
- 并查集专题练习(一)POJ1611
- 数据结构专题小结:并查集
- 并查集专题-1001 Freckles
- 【各大OJ】并查集专题
- 并查集专题训练解题报告
- 并查集专题: HDU1232畅通工程
- 【并查集入门专题1】F
- 【并查集入门专题1】E
- 并查集学习
- 并查集学习
- 并查集学习
- 并查集学习
- android中的指针简述
- 对策字符串的最大长度
- cocos2d学习记录(一)-初步理解
- Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)
- linux-基本命令1
- 并查集专题学习
- 菜鸟学 oracle中的触发器
- VC6.0 将鼠标限定在客户区域内
- 应当怎样合理选择CRM软件
- 大数乘法(加法)运算
- 组合模式使用因素
- How to use C++
- ASP.NET DATAGRIDVIWE控件导出Execle
- 企业ERP选型的三步曲:学医 看病 抓药