【$Kruskal$重构树·入门篇】瓶颈生成树问题的杀手

\(Preface\)

听说\(Kruskal\)重构树是一个冷门数据结构?怀有这种想法的人大可去看看NOI2018Day1T1以及APIO2020T2,看看它的重要性。

\(Kruskal\)重构树一般用于做只能在边权大于等于/小于等于\(v\)的边上走路之类的问题,它具有许多奇妙的性质。

构建方法

\(Kruskal\)\(MST\)的算法应该是众所周知的,而\(Kruskal\)重构树的构建就建立在这一算法的基础上。

根据\(Kruskal\)算法的思想,要先将边按边权排序,然后每次选出权值最大/最小且两端尚未连通的边,将这条边加入到\(MST\)中。

\(Kruskal\)重构树会把\(MST\)中的边也看作点,对于每个连通块都要维护一棵二叉树。

每当选出一条新边时,就让它作为它连接的两个连通块的根节点的父亲。

显然,最终会建成一棵由\(2n-1\)个节点构成的二叉树,而这就是\(Kruskal\)重构树。

性质

  1. \(Kruskal\)重构树中的叶节点对应原图中的点,非叶节点对应原图中的边。
  2. 令每个非叶节点的点权为所对应边的边权,根据\(Kruskal\)重构树的建法,任意一条从非叶节点到根节点的路径,所经点的点权必然是单调的。
  3. 对于原图中的两点\(x,y\),从\(x\)\(y\)的瓶颈就是\(Kruskal\)重构树中\(LCA(x,y)\)的点权。

重要结论

\(x\)出发只经过边权大于等于/小于等于\(v\)的边所能到达的点集,就是\(x\)深度最小点权大于等于\(v\)/小于等于\(v\)的祖先子树内所有的叶节点。(可由性质\(3\)推导)

实际求解时可以利用性质\(2\)中点权的单调性倍增上跳\(O(logn)\)求出这个祖先。

[NOI2018] 归程

  • 给定一个无向图,每条边有一个长度以及一个海拔。
  • 多组询问,每次给定起点以及一个限制\(h\)。要求从起点出发,先开车走海拔大于等于\(h\)的边到达某一节点,然后步行到达\(1\)号点。求最短的步行路程。
  • 数据组数\(\le 3\)\(n\le2\times10^5\)\(m\le2\times10^5\)\(Q\le4\times 10^5\)。(强制在线)

以海拔为关键字建出原图的\(Kruskal\)生成树。

根据先前提到的重要结论,我们可以\(O(logn)\)求出从起点出发开车能到达的点集,而答案就是这些点到\(1\)号点的最短路的最小值。

每个点到\(1\)号点的最短路可以事先\(Dijkstra\)预处理。

只要对于\(Kruskal\)重构树上的每个点维护一下子树内叶节点最短路的最小值即可。

于是一道NOI题目就这样做完了。

\(Postscript\)

唔姆,发现NOI似乎特别喜欢图论题?

觉得一些图论算法还是非常有必要的,尽管重复考的概率不大,但万一呢?

posted @ 2020-08-21 20:50  童女讴歌的荣华帝政  阅读(159)  评论(0编辑  收藏  举报