算法介绍
Kruskal 重构树就是在 Kruskal 算法过程中重新建出了一棵树,这棵树具有一些优美的性质可以解决一类问题,下面就详细叙述一下:
首先复习一下什么是 Kruskal 算法,本质上来说这是一种贪心算法,用于解决最小生成树的问题,把所有边权由小到大排序,用并查集维护连通性,若当前边 ( u , v ) (u,v) (u,v) 不联通,就把当前边加入到最小生成树中。
下面说说什么是 Kruskal 重构树,在 krusakl 算法过程中,每当一条边 ( u , v ) (u,v) (u,v) 被加入最小生成树,令 g u = r o o t ( u ) gu=root(u) gu=root(u), g v = r o o t ( v ) gv=root(v) gv=root(v),我们新建一个虚拟节点作为 g u , g v gu,gv gu,gv 的父亲。这样的过程结束后,我们得到一棵树,这就是 Kruskal 生成树。
它有什么性质呢?
- 最显然的,原图的所有节点都是叶子节点。
- 这棵树是一个二叉树。
但这并不是重点,如果我们在合并时把虚拟的父亲节点的点权设为当前边的权,我们就能真正发现其美妙之处:
- 这是一个大根堆
- 最重要的,也是最好用的性质,就是对于原节点 u , v u,v u,v 来说,其所有路径上最小的最大值就是重构树上 l c a ( u , v ) lca(u,v) lca(u,v) 的点权。
另外,我们可以知道,如果我们用 Kruskal 求最大生成树的话, l c a ( u , v ) lca(u,v) lca(u,v) 的点权是其所有路径上最大的最小值。
这个东西,不得不说实在是太强了…
下面在我们开始我们的思维旅程之前,来道小练习热热身(误)。
[IOI2018]狼人
题意简述:你有两个形态,人形和狼形,现在有一张 n n n 个点, m m m 条边的无向图,有