支配树学习日志
Posted dev-cpp
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了支配树学习日志相关的知识,希望对你有一定的参考价值。
支配树 学习日志
给定一张有向图 $G=(V, E)$,其中 $lvert V vert=n, lvert E vert=m$,以及根 $r in V$。
我们称顶点 $x (x e r)$ 可达,当且仅当存在一条从 $r$ 到 $x$ 的路径。
对于 $x e r$ 且可达的 $x$,如果 $y e x$,且删去 $y$ 后 $x$ 不可达,那么就说 $y$ 支配 $x$。特别地,$r$ 一定支配 $x$。
不可达的点的支配点没有定义,因此我们不妨设 $G$ 的所有顶点都可达。
我们以 $r$ 为根,进行一次深度优先遍历 $ ewcommand{dfs}{mbox{dfs}}(dfs)$。那么,$x$ 的支配点一定都在 $dfs$ 树上从 $r$ 到 $x$ 的路径上,也就是 $x$ 的支配点一定是 $dfs$ 树上 $x$ 的祖先。
我们定义 $x$ 的直接支配点 $mbox{idom}(x)$ 是 $dfs$ 树上深度最大的支配 $x$ 的顶点。
我们构造一张新的有向图 $T=(V,E_T)$,其中 $E_T=ig{langle mbox{idom}(x), x angle igvert x in Vsetminus{r}ig}$。根据上面的结论,我们知道这张有向图是一棵以 $r$ 为根的树,称为支配树。
不难发现,一个点在支配树上的祖先集合就是其支配点集合。
求解 DAG 的支配树
按照拓扑序加入结点。
定义 $ ewcommand{lca}{mbox{LCA}}lca S$ 表示:当前所有已经加入的结点的支配树上,顶点集合 $S$ 的所有元素的最近公共祖先。
$$mbox{idom}(x)=egin{cases}r&mbox{if }langle r, x angle in E;\lca{mbox{idom}(y)midlangle y, x angle in E}&mbox{if }langle r, x angle otin E.end{cases}$$
按照上述式子递推,用倍增求 $lca$,时间复杂度为 $O(mlog n)$。
求解支配树的 $mbox{Lengauer-Tarjan}$ 算法
设 $mbox{fa}_x$ 表示顶点 $x$ 在 $dfs$ 树上的祖先 $(x e r)$,$mbox{sub}_x$ 表示顶点 $x$ 在 $dfs$ 树上的子树顶点集(特殊地,$x in mbox{sub}_x$)。
记顶点 $u < v$,当且仅当 $u$ 在 $v$ 之前被遍历到。
记 $ ewcommand{anc}{dashrightarrow}u anc v$ 表示 $u$ 是 $v$ 在 $dfs$ 树上的祖先。对于 $u anc v$,记 $[u, v]$ 表示在 $dfs$ 树上 $u$ 到 $v$ 的唯一简单路径,$(u, v]$ 表示不含 $u$ 的树上 $u$ 到 $v$ 的简单路径。
如果顶点 $x, y (x e r)$ 满足 $yanc x$,且存在一条路径 $y o v_1 o v_2 o cdots o v_k o x$ 使得 $v_1, v_2, ldots, v_k>x$,就说 $y$ 半支配 $x$ 。
我们定义 $x$ 的半支配点 $mbox{semi}(x)$ 是 $dfs$ 树上深度最小的半支配 $x$ 的顶点。
我们给出求解半支配点的公式:
$$mbox{semi}(x)=minig({umidlangle u,x anglein E}cup{mbox{semi}(v)mid v > x, exists w in V, langle w,x angle in E wedge v anc w}ig)$$
根据半支配点,我们再给出计算 $mbox{idom}(x)$ 的公式:
设 $u$ 是路径 $(mbox{semi}(x), x]$ 上 $mbox{semi}(u)$ 最小的点。
$$mbox{idom}(x)=egin{cases}mbox{semi}(x)&mbox{if }mbox{semi}(x)=mbox{semi}(u);&(1)\mbox{idom}(u)&mbox{if }mbox{semi}(x) e mbox{semi}(u).&(2)end{cases}$$
我们在计算 $mbox{semi}(x)$ 的同时计算能够直接得出的 $mbox{idom}(x)$,或者记录 $u_x$ 满足 $mbox{idom}(x)=mbox{idom}(u_x)$。
我们最后按照 $dfs$ 序递推 $(2)$ 式,建出支配树。
算法实现上,为了查找 $dfs$ 树上祖先后代路径 $(mbox{semi}(x), x]$ 上 $mbox{semi}(u)$ 最小的 $u$,我们可以按照逆 $dfs$ 序加入点,利用带权并查集维护。我们计算直接支配点的过程中,我们用链表等数据结构维护一个集合 $B_y(x)={u in mbox{sub}_y mid mbox{semi}(u)=x}$,其中 $x=mbox{fa}_y$。当顶点 $x$ 的子树处理完毕时,结算 $B_y(mbox{fa}_x)$ 的所有元素的直接支配点。实现时,由于这些 $B_y(x)$ 的生存周期互不相交,我们可以只维护一个 $B(x)$ 表示当前的 $B_y(x)$,结算后清空 $B(x)$ 转到下一棵子树即可。该算法时间复杂度为 $O(m log n)$。
通过解决支配树问题获得的一些启发
$lca$ 的 $mbox{Tarjan}$ 算法中利用了并查集来维护一类离线查询路径信息的问题,这种做法依然是支配树的 $mbox{Lengauer-Tarjan}$ 算法中的关键一步。
后记
- 上述式子的证明还需阅读并研究。
- 这种带权并查集不但可以路径压缩,而且还可以通过一定技巧按秩合并,将时间复杂度降为 $Oig(m alpha(n)ig)$。
以上是关于支配树学习日志的主要内容,如果未能解决你的问题,请参考以下文章