LG5180[模板]支配树【Lengauer-Tarjan算法】

LG5180[模板]支配树【Lengauer-Tarjan算法】

转载自https://www.luogu.org/problemnew/solution/P5180

来一个$Tarjan$老爷子的$Lengauer-Tarjan$算法吧

最优是$O(nα(n))$ 但是会被卡成$O(nlogn)$

(这里默认nm数量级同阶)

1.定义

对于一棵可以存在环的有向图

给定一个起点$r$ 对于一个终点$x$ 如果$r$到达$x$的所有路径都会经过一个点$y$

那么我们就称之为$y$支配$x$

我们令支配$x$的点集为$S=p_1,p_2,p_3,......,p_k$

那么从起点$r$到达$x$的任意一条路径排列为$r......p_1......p_2......p_k...x$

支配树可以对于每一个点$x(x!=r)$求出$p_k$ 也就是点集$S$当中距离$x$最近的支配点

这个点我们称之为$idom[x]$

如果每一个点连出指向$idom[x]$ 那么就构成了一颗内向树 我们称之为支配树

2.算法

1.首先我们需要一颗$DFS$树

也就是对这个算法进行$dfs$遍历 求出其$dfs$序

2.半必经点

从$y$出发到$x$ 存在这样一条路径 路径上的点(不包括$x$以及$y$)的$dfn$均大于$dfn[x]$ 我们称$y$是$x$的半必经点

$sdom[x]$表示$x$的半必经点中$dfn$最小的点

为什么要求这个点呢 ? ? ? 我们删掉原图中的非树边 然后连接$(sdom[x],x)$ 不改变原图中的支配点关系

这样的话 我们就把原图变为了一个$DAG$ 就可以使用$DAG$的做法了 但是还有更优的方法

求半支配点

对于一个点$x$ 找出所有的边$(y,x)$中对应的$y$

若$dfn[y] < dfn[x]$且$dfn[y]$比当前找到的$sdom[x]$的$dfn$小 那么就用$sdom[x]=y$

若$dfn[y]>dfn[x]$ 找到树上$y$的一个祖先$z$ 并且$dfn[z]>dfn[x]$ 比较$dfn[sdom[z]]$同$dfn[sdom[x]]$ 决定是否用前者更新后者

从半支配点到支配点

对于$x$ 我们要的是$idom[x]$

寻找方法如下

我们令$P$是从$sdom[x]$到$x$的树上路径点集(不包括$sdom[x]$) 而且$z$是$P$中$dfn[sdom[z]]$最小的点

如果$sdom[z]=sdom[x]$ 那么$idom[x]=sdom[x]$ 否则就是$idom[x]=idom[z]$

算法流程

我们用带权并查集来实现

首先按照$dfs$序从大到小处理 每一次处理完毕一个点之后 将这个点同其在$dfs$树上的父亲在并查集连边

而并查集的权 就是并查集这个点到根节点的路径上的所有点 最小的$dfn[sdom[x]]$对应的$x$

找$sdom[]$直接找即可 找$idom$可以使用$sdom[x]$处理

猜你喜欢

转载自www.cnblogs.com/ZICLEX/p/10323024.html