ACM数据结构-并查集
ACM数据结构-并查集
并查集,在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。这一类问题近几年来反复出现在信息学的国际国内赛题中,其特点是看似并不复杂,但数据量极大,若用正常的数据结构来描述的话,往往在空间上过大,计算机无法承受;即使在空间上勉强通过,运行的时间复杂度也极高,根本就不可能在比赛规定的运行时间(1~3秒)内计算出试题需要的结果,只能用并查集来描述。
并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。常常在使用中以森林来表示。
主要操作
初始化
查找
合并
部分代码如下:
const int MAXSIZE = 100005; int pre[MAXSIZE]; void makeSet(int size)
{
for(int i=0;i<size;i++)
pre[i]=i;
}
接下来find操作
int find(int x)
{
int r=x;
while(r!=pre[r])
r=pre[r];
return r;
} void Merge(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)
pre[fx]=fy;
}
下面是两个版本的find操作:
int find(int x)
{
if(x!=pre[x])
pre[x]=find(pre[x]);
return pre[x];
}
递归版
int find(int x)
{
int r=x , t;
while(pre[r]!=r)
r=pre[r]; //返回根节点
while(r!=x) //路径压缩
{
t=pre[x];
pre[x]=r;
x=t;
}
return x;
}
非递归版
最后是合并操作 unionSet,并查集的合并也非常简单,就是将一个集合的树根指向另一个集合的树根,如图 所示。

这里也可以应用一个简单的启发式策略——按秩合并。该方法使用秩来表示树高度的上界,在合并时,总是将具有较小秩的树根指向具有较大秩的树根。简单的说,就是总是将比较矮的树作为子树,添加到较高的树中。为了保存秩,需要额外使用一个与 pre 同长度的数组,并将所有元素都初始化为 0。
void unionSet(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx==fy)
return ;
if(rank[fx]>rank[fy])
pre[fy]=fx;
else
{
pre[fx]=fy;
if(rank[fx]==rank[fy])
rank[fy]++;
}
}
除了按秩合并,并查集还有一种常见的策略,就是按集合中包含的元素个数(或者说树中的节点数)合并,将包含节点较少的树根,指向包含节点较多的树根。这个策略与按秩合并的策略类似,同样可以提升并查集的运行速度,而且省去了额外的 rank 数组。
这样的并查集具有一个略微不同的定义,即若 uset 的值是正数,则表示该元素的父节点(的索引);若是负数,则表示该元素是所在集合的代表(即树根),而且值的相反数即为集合中的元素个数。相应的代码如下所示,同样包含递归和非递归的 find 操作:
const int MAXSIZE = 1000005; int pre[MAXSIZE]; void makeSet(int size)
{
for(int i = 0;i < size;i++)
pre[i] = -1;
} int find(int x)
{
if (pre[x] < 0)
return x;
pre[x] = find(pre[x]);
return pre[x];
} int find(int x)
{
int r = x, t;
while (pre[r] >= 0)
r = pre[r];
while (x != r)
{
t = pre[x];
pre[x] = r;
x = t;
}
return x;
} void unionSet(int x, int y)
{
int fx = find(x);
int fy = find(y);
if (fx==fy)
return;
if (pre[fx] < pre[fy])
{
pre[fx] += pre[fy];
pre[fy] = fx;
}
else
{
pre[fy] += pre[fx];
pre[fx] = fy;
}
}
如果要获取某个元素 x 所在集合包含的元素个数,可以使用 -pre[find(x)] 得到。
ACM数据结构-并查集的更多相关文章
- 算法手记 之 数据结构(并查集详解)(POJ1703)
<ACM/ICPC算法训练教程>读书笔记-这一次补上并查集的部分.将对并查集的思想进行详细阐述,并附上本人AC掉POJ1703的Code. 在一些有N个元素的集合应用问题中,通常会将每个元 ...
- ACM: The Suspects-并查集-解题报告
The Suspects Time Limit:1000MS Memory Limit:20000KB 64bit IO Format:%lld & %llu Description 严重急性 ...
- 图论&数据结构——并查集
Wikioi 4246 NOIP模拟赛Day2T1 奶牛的身高 题目描述 Description 奶牛们在FJ的养育下茁壮成长.这天,FJ给了奶牛Bessie一个任务,去看看每个奶牛场中若干只奶牛的 ...
- POJ 1703 Find them, Catch them (数据结构-并查集)
Find them, Catch them Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 31102 Accepted: ...
- acm专题--并查集
题目来源:http://hihocoder.com/problemset/problem/1066 #1066 : 无间道之并查集 时间限制:20000ms 单点时限:1000ms 内存限制:256M ...
- 《挑战程序设计竞赛》2.4 数据结构-并查集 POJ1182 2236 1703 AOJ2170
POJ1182 http://poj.org/problem?id=1182 题目 难得的中文题... 食物链 Time Limit: 1000MS Memory Limit: 10000K Tota ...
- 第三十一篇 玩转数据结构——并查集(Union Find)
1.. 并查集的应用场景 查看"网络"中节点的连接状态,这里的网络是广义上的网络 数学中的集合类的实现 2.. 并查集所支持的操作 对于一组数据,并查集主要支持两种操作:合并两 ...
- 【题解】P2024 [NOI2001]食物链 - 数据结构 - 并查集
P2024 [NOI2001]食物链 声明:本博客所有题解都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 题目描述 动物王国中有三类动物 \(A,B ...
- <数据结构>并查集与树
作用 查:给定一个元素,查询它在哪个集合内 并:合并两个元素所在的集合 实现思路 对应关系 元素-->结点 集合-->树 多个集合-->森林 用树的根节点作为不同树的标志 合并时只需 ...
随机推荐
- RedHat(Linux) Oracle数据库设置开机自启动
1 首先修改/etc/oratab文件添加如下行:ycr:/u01/app/oracle/product/12.1.0/dbhome_1:Y 关于/etc/oratab文件解释如下:# This fi ...
- js中公有方法、特权方法、静态方法
1.公有属性和公有方法 1 2 3 4 5 6 7 8 9 function User(name,age){ this.name = name;//公有属性 this.age = age; } ...
- SQLi-db 批量注入工具+教程
这款工具在中国还没人发.所以我发来给大家玩玩:顺便带了教程. 关键字:inurl:article.asp?id= inurl:article.php?id=inurl:article.jsp?id=( ...
- Oracle 查找带有CLOB字段的所有表
查找带有CLOB字段的以HEHE开头的所有表 select t.column_name ,DATA_TYPE,TABLE_NAMEfrom user_tab_columns twhere t.TABL ...
- List的 并集、交集、差集操作
package com.zheting.collection.list; import java.util.ArrayList; import java.util.Arrays; import jav ...
- 关于Could not obtain transaction-synchronized Session for current thread 这个异常。
Could not obtain transaction-synchronized Session for current thread 这个异常之前非常让我头大.对于网上的各种说法都试了一下反正都不 ...
- SQL 关联两个表的视图总结
视图就是一条select查询语句,是一张虚拟表. table a , table b 以表a基表(a LEFT JOIN b) 1.1 当update view时 更新view中表b字段并且表b ...
- HDU 6470 Count 【矩阵快速幂】(广东工业大学第十四届程序设计竞赛 )
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6470 Count Time Limit: 6000/3000 MS (Java/Others) ...
- 阅读layim代码小记,监听事件实现方法
(function (win) { //注册事件 var chat = function () { $('#open').on('click', function () { sendMessage() ...
- PAT——年会抽奖(错位 排序)
题目描述 今年公司年会的奖品特别给力,但获奖的规矩却很奇葩: 1. 首先,所有人员都将一张写有自己名字的字条放入抽奖箱中:2. 待所有字条加入完毕,每人从箱中取一个字条:3. 如果抽到的字条上写的就是 ...