并查集
并查集是一种数据结构,一般它处理的是图(其实是解决无向图的)的连通分量问题,但是当并查集的根节点可以维护更多的信息时,并查集可以解决范围更广的基于无向图连通分量的问题。做了这么多并查集的题目后,我感觉并查集就是解决有关物与物之间的关系问题的数据结构且这种关系还必须是可传递的关系,所以一般遇到这种问题可以先尝试用并查集解决。
并查集的基本代码,一般用于解决基础应用类型的问题:
有N个城市,每次给出(u,v)这种数据对表示u城市与v城市有一条路连通,给了M条数据对之后,问你X城市与Y城市是否相通(间接或直接都行)?
下面给出并查集对应的习题。并查集题目我分成了3类:基础应用,维护信息,路径压缩。其实都不难,但是如果没做过下面相应的题目想要解决对应并查集的问题,可能就有难度。建议从下面题目的顺序刷一遍,基本并查集的思想就能有深刻的体会。
第一次接触并查集的同学,强烈建议你在做第一道题目HDU 4496的时候自己想想 对任意一个节点i执行findset(i)操作后,并查集的图会发生什么变化(可以就 fa[1]=2,fa[2]=3,fa[3]=4,这个图执行findset(1)后,各节点的fa值有什么变化 画个图分析一下)。
并查集基础应用:
HDU 4496 D-CITY(并查集): 并查集基础应用。解题报告!
HDU 1213 How Many Tables(并查集): 并查集基础应用。解题报告!
HDU 1198 Farm Irrigation(并查集): 并查集基础应用,不过注意一些细节边界条件。解题报告!
UVA 1160 X-Plosives(并查集): 并查集基础应用,需要先转化一下思维。解题报告!
HDU 1232 畅通工程(并查集): 并查集基础应用。解题报告!
HDU 1272 小希的迷宫(并查集:判断连通且结构为树): 并查集基础应用。解题报告!
HDU 1325 POJ 1308 Is It A Tree?(并查集):并查集基础应用。解题报告!
POJ 2236 Wireless Network(并查集):并查集基础应用,不要做一些预处理。解题报告!
POJ 2524 Ubiquitous Religions(并查集):并查集基础应用。解题报告!
POJ 1456 Supermarket(贪心算法,可用并查集优化):本题的重点其实是贪心算法,不过并查集优化也做得很巧妙。解题报告!
ZOJ 3261 Connections in GalaxyWar(并查集:离线处理):并查集的基础应用,本题需要离线处理所有请求,先理清思路再写代码否则容易出错。解题报告!
POJ 2253 Frogger(并查集+二分):并查集基础应用,需要二分跳跃距离然后判断可行性。解题报告!
ZOJ 3321 Circle(并查集):并查集基础应用。解题报告!
并查集根节点维护信息:
POJ 1611 The Suspects(并查集): 可以用根节点维护num信息来做。解题报告!
ZOJ 3659 Conquera New Region (并查集:维护根节点信息):需要维护当前根节点的有效信息。解题报告!
并查集路径压缩
UVA 1329 Corporative Network(并查集:路径压缩):路径压缩并查集入门。解题报告!
HDU 3635 Dragon Balls(并查集:路径压缩):路径压缩并查集,其实本质上与根节点维护信息的并查集很相似。解题报告!
POJ 1182 食物链(并查集:路径压缩): 路径压缩并查集典型应用,搞懂这题目基本就搞懂了路径压缩并查集问题。解题报告!
POJ 1703 Find them, Catch them(路径压缩并查集): 路径压缩并查集。解题报告!
POJ 1984 Navigation Nightmare(路径压缩并查集):路径压缩并查集问题的略微变形问题。解题报告!
POJ 1988 Cube Stacking(路径压缩并查集):路径压缩并查集,需要维护的信息有点特别。解题报告!
POJ 2492 A Bug's Life(路径压缩并查集):简单的路径压缩并查集问题。解题报告!
POJ 1733 Parity game(路径压缩并查集+离散化):有一定难度的路径压缩并查集问题。解题报告!
HDU 3038 How Many Answers AreWrong(路径压缩并查集): 本题也是区间有关的,与POJ 1733类似,不过比它简单不用离散化。解题报告!
POJ 2912 Rochambeau(路径压缩并查集): 本题本质上也是路径压缩并查集,但是本题需要枚举,还需要分析逻辑。解题报告!
POJ 1417 True Liars(路径压缩并查集+DP背包问题):本题需要最后用DP 01背包的解法来判断是否存在唯一解。解题报告!
问题1:检验一个节点i是不是所属连通分量的根节点用下面代码行吗?
代码1:if(fa[i]==-1)
代码2:if(findset(i)==-1)
上述代码1是对的,但是代码2是错的。
问题2:如何快速计算无向图还剩多少个连通分量?
初始连通分量为n,每进行一次有效的bind(当bind返回1时表示进行了有效的合并)操作,就会使得连通分量数目-1。所以最终连通分量数目为:n – 有效bind操作的次数。