【数据结构与算法】并查集基础

1、介绍

并查集是一种树型数据结构,用于处理一些不相交集合的合并问题。

并查集主要操作有:

  (1)合并两个不相交集合;

  (2)判断两个元素是否属于同一个集合;

  (3)路径压缩;

2、常用操作

用father[i]表示元素i的父亲结点,例如:

用某个元素所在树的根节点表示该元素所在集合;

判断两个元素是否属于同一个集合的时候,只需要判断他们所在树的根节点是否一样即可;

也就是说,当我们合并两个集合的时候,只需要在两个根节点之间连边即可。

获取根节点代码:

1 int findFather(int x){
2     if(father[x] == x)
3         return x;
4     else
5         return findFather(father[x]);
6 }

判断是否属于同一集合代码:

1 bool judge(int x,int y){
2     int fx,fy;
3     fx = findFather(x);
4     fy = findFather(y);
5     return fx==fy;
6 }

合并不同元素到同一集合代码:

1 void unionSet(int x,int y){
2     x = findFather(x);
3     y = findFather(y);
4     father[x] = y;
5 }

3、优化1——路径压缩

思想

每次查找的时候,如果路径较长,则修改信息,以便下次查找的时候速度更快;

步骤

(1)找到根节点;

(2)修改查找路径上的所有结点,将他们都指向根节点;

例如查找下面并查集中的“20”,“9,10,20”均在查找路径上,则进行路径压缩

带路径压缩的查找算法代码

 1 int findFather(int x){
 2     int r = x;
 3     //get the root of x
 4     while(father[r] != r)
 5         r = father[r];
 6     int i=x;
 7     //update the nodes in searching path
 8     while(i != r){
 9         j = father[i];
10         father[i] = r;
11         i = j;
12     }
13     return r;
14 }

4、优化2-合并

思想

两个集合合并,也就是2棵树合并,为了降低合并后的树的深度,一般采取将深度小的树的树根作为深度大的树的树根的孩子节点。

策略

增加辅助空间记录树的深度。

合并代码:

 1 void unionSet(int x,int y){
 2     x = findFather(x);
 3     y = findFather(y);
 4     if(x == y)
 5         return ;
 6     if(rank[x] > rank[y]){
 7         father[y] = x;
 8     }else{
 9         if(rank[x] == rank[y])
10             rank[y]++;
11         father[x] = y;
12     }
13 }

5、并查集例题

5.1、HDOJ1232(畅通工程)

http://www.cnblogs.com/CheeseZH/archive/2012/05/13/2498073.html

5.2、HDOJ1272(小希的迷宫)

http://www.cnblogs.com/CheeseZH/archive/2012/05/25/2518639.html

6、并查集练习题

(1)银河英雄传说(NOI2002)

(2)食物链(NOI2001)

(3)Parity(ceoi99)

时间: 2024-08-26 15:05:17

【数据结构与算法】并查集基础的相关文章

模板——最小生成树kruskal算法+并查集数据结构

并查集:找祖先并更新,注意路径压缩,不然会时间复杂度巨大导致出错/超时 合并:(我的祖先是的你的祖先的父亲) 找父亲:(初始化祖先是自己的,自己就是祖先) 查询:(我们是不是同一祖先) 路径压缩:(每个点只保存祖先,不保存父亲) 最小生成树kruskal:贪心算法+并查集数据结构,根据边的多少决定时间复杂度,适合于稀疏图 核心思想贪心,找到最小权值的边,判断此边连接的两个顶点是否已连接,若没连接则连接,总权值+=此边权值,已连接就舍弃继续向下寻找: 并查集数据结构程序: #include<ios

【HDU1232】畅通工程(并查集基础题)

裸敲并查集,很水一次AC 1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cstdio> 5 #include <cctype> 6 #include <cmath> 7 #include <algorithm> 8 #include <numeric> 9 #include <string> 1

【HDU1856】More is better(并查集基础题)

裸并查集,但有二坑: 1.需要路径压缩,不写的话会TLE 2.根据题目大意,如果0组男孩合作的话,应该最大的子集元素数目为1.所以res初始化为1即可. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <numeric> 7 #include <

Codeforces Round #254 (Div. 2) DZY Loves Chemistry【并查集基础】

一开始不知道题意是啥意思,迟放进去反应和后放进去反应有什么区别 对于第三组数据不是很懂,为啥312,132的组合是不行的 后来发现这是一道考察并查集的题目 QAQ 怒贴代码: 1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <math.h> 5 #include <iostream> 6 #include <algorithm> 7

【HDU1325】Is It A Tree?(并查集基础题)

有以下坑点: 1.结束输入不一定-1,题目中的叙述只是说所有权值都为正值. 2.是否构成一棵树不能只判断是否只有一个根节点,没有环路,而且还需要判断每个节点的入度一定是1,不然就不是一棵树. (无环路也可用树的性质:结点数 = 边树 + 1 来取代) 1 #include <iostream> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cctype> 5 #include <cmath&

【HDU2120】Ice_cream&#39;s world I(并查集基础题)

查环操作,裸题.一次AC. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cctype> 5 #include <cmath> 6 #include <string> 7 #include <cstdio> 8 #include <algorithm> 9 #include <numeric>

【HDU1231】How Many Tables(并查集基础题)

什么也不用说,并查集裸题,直接盲敲即可. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cstdio> 5 #include <cctype> 6 #include <cmath> 7 #include <algorithm> 8 #include <numeric> 9 using namespace s

[经典算法]并查集

概述: 并查集(Union-find Sets)是一种非常精巧而实用的数据结构,它主要用于处理一些不相交集合的合并问题.一些常见的用途有求连通子图.求最小生成树的 Kruskal 算法和求最近公共祖先(Least Common Ancestors, LCA)等. 使用并查集时,首先会存在一组不相交的动态集合 S={S1,S2,?,Sk},一般都会使用一个整数表示集合中的一个元素. 每个集合可能包含一个或多个元素,并选出集合中的某个元素作为代表.每个集合中具体包含了哪些元素是不关心的,具体选择哪个

算法 - 并查集

并查集 - 知乎专栏 POJ 1611(并查集+知识) POJ 2524(并查集) 这个时候我们就希望重新设计一种数据结构,能够高效的处理这三种操作,分别是 MAKE-SET(x),创建一个只有元素x的集合,且x不应出现在其他的集合中 UNION(x, y),将元素x所在集合Sx和元素y所在的集合Sy合并,这里我们假定Sx不等于Sy FIND-SET(x),查找元素x所在集合的代表 并查集的具体实现. 对于有根树或者说森林的表示,可以用一个数组parent来实现. parent[i]记录元素i的