Live2D

支配树(灭绝树) 学习笔记

前言

在飞机上的时候理解了一下这个算法,这里写一下吧。本来以前一直以为是个\(H_2O\)算法(其实也是),结果发现一些证明还是很有意思的。

前置定义

对于一个给定图,我们有如下定义:

  • 支配点

我们称\(u\)\(v\)的支配点当且仅当在原图中删去\(u\)之后从根节点出发无法抵达\(v\)

  • 半支配点

我们称\(u\)\(v\)的半支配点当且仅当\(u\)存在一条到\(v\)的路径使得该路径除去\(u,v\)所有节点的\(dfn\)都大于\(dfn[v]\),且\(u\)在满足条件的点集中\(dfn\)最小。

为了方便,我们称点\(u\)的半支配点为\(sdom[u]\),支配点为\(idom[u]\)

支配树思想

这个算法主要是解决支配之类的问题。例如一个点支配多少个点,一个点被多少个点支配之类的。

对于这个问题我们可以建起一棵树,满足点\(u\)支配的点都在\(u\)的子树内。

于是问题就是如何建起一棵支配树,据说这个还叫灭绝树(奇怪的名字增加了!!!)

很显然,对于一棵树,该树的支配树就是它本身。

  • \(\text {DAG}\)

很显然,我们可以直接把点\(u\)连在\(lca(v_1,v_2,...)\)的下面,其中存在边\(v_1,v_2,...\to u\)

时间复杂度\(\Theta(n\log n)\)

例题: [ZJOI2012]灾难

  • 任意图

对此,我们\(\text {Tarjan}\)老爷子和\(\text {Lengauer}\)提出了一种名为\(\text {Lengauer-Tarjan}\)的算法,可以在\(\Theta(n\log n)\)的时间复杂度内建好树,当然,更确切的来说是\(\Theta(n\alpha (n))\)

我们发现似乎我们直接求支配点不是很好求,我们考虑如何求出半支配点。

我们发现对于当前节点\(u\),如果有边\(v\to u\),且\(dfn[u]<dfn[v]\),那么在不考虑\(dfn\)最小的情况下,一定\(sdom[v]\)\(u\)的半支配点。

证明直接感性一下,发现显然,直接根据定义就可以知道正确性。

而且半支配点还有一个性质,就是一个点的半支配点的\(dfn\)一定不会比该点大,这个下面的性感证明会用到,但是我似乎并没有写出来,读者明白就好。

然后这里就有一个\(\Theta(n\log n)\)的方法诞生了。我们发现如果删掉原图中非\(dfs\)树的边,再对于\(\forall u\),连上\(sdom[u]\to u\),不会改变原图的支配关系。

正确性这里感性证明一下,对于\(u,v\),如果在原图中\(u\)并不支配\(v\),那么,如果在\(dfs\)树中\(u\)不是\(v\)的祖先,那显然满足,否则的话,我们可以从\(sdom[v]\)走到\(v\)。如果原图中\(u\)支配\(v\)的话,很显然,在\(dfs\)树中\(u\)\(v\)的祖先,因为无论怎么走都得先经过\(u\)。那么显然\(u\)还支配\(v\)

于是,我们就把这个图变成了一个\(\text {DAG}\),就可以用上面的方法\(\Theta(n\log n)\)做出来了。

但是,这并不满足我们对代码复杂度的渴望。一个小小的思想在我们脑海中划过:我们是否可以用\(sdom\)求出\(idom\)?答案是肯定的。为了方便,我们假设我们已经把图变成一个\(\text {DAG}\)了。

我们分两种情况考虑:

我们设\(z\)\(sdom[x]\to x\)路径上\(dfn[sdom[z]]\)最小的点

  1. 如果\(sdom[z]=sdom[x]\)

\(idom[x]=sdom[x]\)

这个应该很显然吧。。。性感理解的话就是因为不可能有其他点通过\(sdom\)边走到\(sdom[x]\to x\)的路径上,因为这条路径上\(dfn[sdom[z]]\)最小值也不过\(sdom[x]\)

  1. 否则

\(idom[x]=idom[z]\)

我们采用反证法来感性证明一下:

我们假设删去\(idom[z]\)之后仍可达\(idom[x]\),那么说明\(idom[z]\)的某个祖先可以通过\(sdom\)边走到\(idom[z]\to x\)这条路径上的某个点,但是我们发现\(idom[z]\)必定是\(sdom[z]\)的后代,而\(sdom[z]\to z\)这条路径上\(dfn[sdom[z]]\)最小也不过\(z\),所以矛盾,证毕。

于是,我们可以用并查集维护\(sdom[x]\to x\)\(dfn[sdom[\ \ ]]\)的最小值,我们就在\(\Theta(n\alpha(n))\)的时间复杂度内解决了建树的问题。

对了,还有最后的一个问题没有解决,可能细心的读者已经发现了(似乎也木有什么读者),我们并没有说明一个点支配的点都在支配树的子树内。其实很好说明,我们发现我们全都是用的\(dfn\)最小的点,这就满足充分性。

\(\text {The 1st}\)

P5180 【模板】支配树

这个题确实就是板题,就是建出支配树后求出子树大小。

代码戳这里打开

\(\text {The 2ed}\)

题目大意

给出一个\(n\)个点\(m\)条边的带权无向图,给定起点\(s\),求出一个点使得删去该点之后最短路变化的点数最多。

思路

这道题其实还是比较妙的。

我们不难想到先对原图建出一个最短路径图,于是一个点删去产生的贡献就是该图中支配的点数。这个仔细想一下就会明白为什么。

我们发现这个最短路径图一定是个\(\text {DAG}\),因为里面如果有环的话就不是最短路径图了,于是我们就可以直接用\(\text {LCA}\Theta(n\log n)\)解决。

于是我们就在\(\Theta(n\log n+m)\)的时间复杂度内解决了这个问题。

代码戳这里打开

posted @ 2020-07-10 19:10  Dark_Romance  阅读(385)  评论(0编辑  收藏  举报