支配树笔记
鉴于原论文对半支配点的定义有点抽象,本文在不引入半支配点的概念下介绍支配树及所求算法。
定义1.1:在一张有向图中,给定起点\(s\),若删除点\(x\)后,\(s\)无法到达\(y\)(\(x\neq y\)),则称\(x\)为\(y\)的支配点,也称\(x\)支配\(y\)、\(y\)被\(x\)支配。特别的,\(s\)是除自身外所有点的支配点。
观察1.1:若\(x\)支配\(y\),\(y\)支配\(z\),则\(x\)支配\(z\)。
观察1.2:支配关系不会出现环。
观察1.3:若\(z\)同时被\(x,y\)支配,则\(x,y\)间存在支配关系。
证明:
若假设\(y\)不支配\(x\)且\(x\)不支配\(y\),但\(z\)同时被\(x,y\)支配
对于任意一条到\(z\)的路径,由对称性不妨设路径先经过\(x\)再经过\(y\),那么我们得到一条从\(y\)出发不经过\(x\)到达\(z\)的路径,由假设知存在一条由\(s\)出发不经过\(x\)到达\(y\)的路径,将两条路径合并得到一条从\(s\)出发不经过\(x\)到达\(z\)的路径,则\(x\)不支配\(z\),与假设矛盾。
定义1.2:根据观察1.2与观察1.3,除\(s\)外的每个点\(x\),必定存在支配点(\(s\)支配所有点),且支配点集里存在某个点\(y\)被集合中的其他所有点支配,若我们将该点为\(x\)的父亲,则可以建议一棵以\(s\)为根的有根树,我们将这棵树称为支配树。
考虑如何求\(\text{DAG}\)的支配树。
观察2.1:\(x\)在支配树上的父亲,为所有在\(\text{DAG}\)中能直接到达\(x\)(即\(\{y|\exists(y,x)\in E\}\))的点在支配树上的\(\text{LCA}\)。
证明:
若\(|\{y|\exists(y,x)\in E\}|=1\),则显然\(x\)父亲为\(y\);
若\(|\{y|\exists(y,x)\in E\}|>1\),则支配\(x\)的点也必然支配所有的\(y\)。
故我们可以求该图的拓扑序,然后按拓扑序逐步建支配树。
下面观察一般有向图的一些性质。
观察3.1:对于任意\(\text{dfs}\)树,\(x\)的支配点一定为\(x\)的祖先。
定义3.1:对于某棵\(\text{dfs}\)树,\([x,y]\)表示\(x\)到\(y\)最短路径的点集,\((x,y)\)表示\(x\)到\(y\)最短路径不包括\(x,y\)的点集。
定义3.2:对于\(x\)的祖先\(y\),若存在从\(y\)出发不经过\((y,x)\)到达\(x\)的路径,则称\(y\)满足条件,令所有满足条件的\(y\)中深度最小的为\(\text{sdom(x)}\)。
除\(s\)外任意点均存在\(\text{sdom(x)}\),因为在\(\text{dfs}\)树上的父亲一定满足条件。
观察3.2:\((\text{sdom(x)},x)\)中任意点不是\(x\)的支配点。
证明:
我们可以构造出从\(s\)出发不经过\((\text{sdom(x)},x)\)中任意点到达\(x\)的路径:\(s\)沿树边到达\(\text{sdom(x)}\),由定义可知存在从\(\text{sdom(x)}\)出发不经过(\text{sdom(x)},x)而到达\(x\)的路径,将两条路径接上即可。
观察3.3:对于\(x\)的某个祖先\(z\),不被\((\text{sdom(x)},x)\)包含,且不被任意\(x\)的祖先\(y\)的\((\text{sdom(y),y})\)包含,是\(z\)为\(x\)支配点的充要条件。
证明:
假设\(z\)被某个包含了,则必定不为支配点。
否则,假设\(z\)未被任何包含,且不为\(x\)的支配点,一定存在从\(s\)到\(x\)不经过\(z\)的路径\(s=v_0,v_1,\cdots,v_m=x\),这条路径中一定存在\(v_{k_1},v_{k_2}\)(\(k_1<k_2\))为\(x\)的祖先,满足\(\forall i\in(k_1,k_2) ,v_i\)均不为\(x\)的祖先且\(v_{k_1},v_{k_2}\)在\(\text{dfs}\)树中的路径包含\(z\),则\(sdom(v_{k_2})\)一定为\(v_{k_1}\)或其祖先,则\((sdom(v_{k_2}),v_{k_2})\)包含\(z\),与\(z\)未被包含矛盾。
若我们得到了所有的\(\{\text{sdom}(i)\}\),那么求支配树父亲将非常简单,下面介绍如何求\(\{\text{sdom}(i)\}\)
先探究\(\{\text{sdom}(i)\}\)的性质
假设\(\text{sdom(x)}\)到\(x\)不经过\((\text{sdom(x)},x)\)的路径中的最后一条边为\((y,x)\),那么有两种情况。
\(1)\):\(y\)为\(x\)的祖先。
\(2)\):最后一条边为横插边或后向边。
对于\(1)\),则此时\(\text{sdom(x)}=y\);
对于\(2)\),不妨设此路径为\(sdom(x)=v_0,v_1,\cdots,v_{m-1}=y,v_m=x\),设路径中第一个位于\((\text{LCA}(x,y),y]\)中的点\(v_k\),一定有\(sdom(v_k)=sdom(x)\),而此路径中其他位于\((\text{LCA}(x,y),y]\)中的点\(sdom\)的深度一定大于等于\(sdom(v_k)\)的深度。
证明:
若\(sdom(v_k)\neq sdom(x)\),由于存在以上路径,\(sdom(v_k)\)的深度一定小于\(sdom(x)\),此时\(sdom(v_k)\)也为\(x\)的祖先,由于存在\(sdom(v_k)\)到\(v_k\)不经过\((sdom(v_k),v_k)\)的路径,此路径必定不经过\((sdom(x),x)\),该路径再依次接\(v_{k+1},\cdots,v_m\)即可得到从\(sdom(v_k)\)到\(x\)不经过\((sdom(v_k),x)\),与\(sdom(x)\)定义矛盾,故\(sdom(v_k)=sdom(x)\)。
若对于此路径中其他位于\((\text{LCA}(x,y),y]\)中的点\(l\),若\(\text{sdom}(l)\)深度小于\(\text{sdom}(v_k)\),即\(\text{sdom}(x)\),我们仍然可以构造出从\(\text{sdom}(l)\)到达\(x\)不经过\((\text{sdom}(l),x)\)的路径,与\(\text{sdom}(x)\)定义矛盾。
由以上,我们得到求\(\text{sdom(i)}\)的算法
枚举\((y,x)\)
\(1)\):\(y\)为\(x\)的祖先,用\(y\)更新\(\text{sdom}(x)\)
\(2)\):\(y\)不为\(x\)的祖先,设\(z\)为\(\text{LCA}(x,y)\),用\((z,y]\)中点的\(\text{sdom}\)更新\(\text{sdom}(x)\)
易知\(2)\)中\(dfn(y)>dfn(x)\),对\(\text{dfn}\)倒序更新\(\text{sdom}\)。