vlambda博客
学习文章列表

数据结构二叉树(六)

并查集的定义

给定n个结点的集合,结点编号为1n,再给定一个等价关系,由等价关系产生所有结点的一个划分,每个结点属于一个等价类,所有等价类是不相交的。

需要求一个结点所属的等价类,以及合并两个等价类。

并查集的实现

数据结构二叉树(六)并查集就是一个森林。

数据结构二叉树(六)每个等价类用一棵树表示,包含该等价类的所有结点,即结点子集,

数据结构二叉树(六)每个子集通过一个代表来识别,代表即该子集中的某个结点,通常选择根做这个代表。

数据结构二叉树(六)

    问题描述:如果已经得到完整的家谱,判断两个人是否亲戚应该是可行的,但如果两个人的最近公共祖先与他们相隔好几代,使得家谱十分庞大,那么检验亲戚关系就十分复杂。在这种情况下,就需要应用并查集。

    为了将问题简化,将得到一些亲戚关系的信息,如MarryTom是亲戚,TomBen是亲戚,等等。从这些信息中,可以推出MarryBen是亲戚。

数据结构二叉树(六)

数据结构二叉树(六)

数据结构二叉树(六)

数据结构二叉树(六)

数据结构二叉树(六)

数据结构二叉树(六)

用有根树来表示集合,树中的每个结点包含集合的一个成员,每棵树表示一个集合。

多个集合形成一个森林,以每棵树的树根作为集合的代表,并且根结点的父结点指向其自身,树上的其他结点都用一个父指针表示它的附属关系。      

数据结构二叉树(六)

在并查集中,每个分离集合对应的一棵树,称为分离集合树。整个并查集也就是一棵分离集合森林。

4个集合{1234}{567}{89}{10},分别以47910表示对应集合的编号。

数据结构二叉树(六)

查找x

数据结构二叉树(六)

查找x所在的子集

数据结构二叉树(六)

合并过程

数据结构二叉树(六)

数据结构二叉树(六)

数据结构二叉树(六)


数据结构二叉树(六)

数据结构二叉树(六)

数据结构二叉树(六)

查找中的路径压缩

数据结构二叉树(六)

并查集的基本存储结构(实际上是森林的双亲存储结构)如下:

数据结构二叉树(六)

并查集的基本运算算法

时间复杂度为O(n)

数据结构二叉树(六)

数据结构二叉树(六)

数据结构二叉树(六)

用迭代方式实现

数据结构二叉树(六)

数据结构二叉树(六)

HDU1232—畅通工程问题。

   问题描述:某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路?

   输入格式:测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是城镇数目NN<1000< span="">)和道路数目M,随后的M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的两个城镇的编号。为简单起见,城镇从1N编号。注意两个城市之间可以有多条道路相通,也就是说:

   3 3

   1 2

   1 2

   2 1

这种输入也是合法的。当N0时,输入结束,该用例不被处理。


数据结构二叉树(六)

数据结构二叉树(六)要使全省任何两个城镇间都实现交通,最少的道路是所有城镇之间都有一条路径,即全部城镇构成一棵树。

数据结构二叉树(六)采用并查集求解,由输入构造并查集,每棵子树中的所有城镇是有路径的,求出其中子树的个数ans,那么最少还需要建设的道路数就是ans-1

数据结构二叉树(六)

数据结构二叉树(六)