OSDN Git Service

更正虚树文章的模拟部分的错误
authorXZYQvQ <konnyakuxzy@outlook.com>
Tue, 2 Oct 2018 14:10:10 +0000 (22:10 +0800)
committerGitHub <noreply@github.com>
Tue, 2 Oct 2018 14:10:10 +0000 (22:10 +0800)
一开始忘记连接1->3的边了

docs/ds/virtual-tree.md

index 297b771..c3f2e6b 100644 (file)
 
 那么步骤是这样的:
 
-- 将 $3$ 个关键点 $6,4,7$(我故意打乱了)按照 DFS 序排序,得到序列 $4,6,7$;
-- 将点 $1$ 入栈;
-- 取序列第一个作为当前节点,为 $4​$,再取栈顶元素,为 $1​$。求 $1​$ 和 $4​$ 的 LCA​:$\text{LCA}(1,4)=1​$;
-- 发现 $\text{LCA}(1,4)$ 为栈顶元素,说明它们在虚树的一条链上,所以直接把当前节点 $4$ 入栈,当前栈为 $4,1$;
-- 取序列第二个作为当前节点,为 $6$。再取栈顶元素,为 $4$。求 $6$ 和 $4$ 的 LCA:$\text{LCA}(6,4)=1$;
-- 发现 $\text{LCA}(6,4)$ 不等于栈顶元素,进入判断阶段;
-- 判断阶段:发现栈顶节点 $4$ 的 DFS 序是大于 $\text{LCA}(6,4)$ 的,但是次大节点(栈顶节点下面的那个节点)$1$ 的 DFS 序是等于 LCA 的(其实 DFS 序相等说明节点也相等),说明 LCA 已经入栈了,所以直接连接 $1\to 4$ 的边,也就是 LCA 到栈顶元素的边。并把 $4$ 从栈中弹出;
-- 结束了判断阶段,将 $6$ 入栈,当前栈为 $6,1$;
-- 取序列第三个作为当前节点,为 $7$。再取栈顶元素,为 $6$。求 $7$ 和 $6$ 的 LCA :$\text{LCA}(7,6)=3$;
-- 发现 $\text{LCA}(7,6)$ 不等于栈顶元素,进入判断阶段;
-- 判断阶段:发现栈顶节点 $6$ 的 DFS 序是大于 $\text{LCA}(7,6)$ 的,但是次大节点(栈顶节点下面的那个节点)$1$ 的 DFS 序是小于 LCA 的,说明 LCA 还没有入过栈,所以直接连接 $3\to 6$ 的边,也就是 LCA 到栈顶元素的边。把 $6$ 从栈中弹出,并且把 $\text{LCA}(6,7)$ 入栈。
-- 结束了判断阶段,将 $7$ 入栈,当前栈为 $3,7$;
-- 发现序列里的 $2$ 个节点已经全部加入过栈了,退出循环;
-- 此时栈中还有 $2$ 个节点:$3,7$,很明显它们是一条链上的,所以直接链接 $3\to 7$的边;
+- 将3个关键点$6,4,7$(我故意打乱了)按照dfs序排序,得到序列$4,6,7$
+- 将点$1$入栈
+- 取序列第一个作为当前节点,为$4$。再取栈顶元素,为$1$。求$1$和$4$的$LCA$:$LCA(1,4)=1$。
+- 发现$LCA(1,4)=$栈顶元素,说明它们在虚树的一条链上,所以直接把当前节点$4$入栈,当前栈为$4,1$
+- 取序列第二个作为当前节点,为$6$。再取栈顶元素,为$4$。求$6$和$4$的$LCA$:$LCA(6,4)=1$。
+- 发现$LCA(6,4)!=$栈顶元素,进入判断阶段。
+- 判断阶段:发现栈顶节点$4$的Dfs序是大于$LCA(6,4)$的,但是次大节点(栈顶节点下面的那个节点)$1$的Dfs序是等于$LCA$的(其实Dfs序相等说明节点也相等),说明$LCA$已经入栈了,所以直接连接$1->4$的边,也就是$LCA$到栈顶元素的边。并把$4$从栈中弹出。
+- 结束了判断阶段,将$6$入栈,当前栈为$6,1$
+- 取序列第三个作为当前节点,为$7$。再取栈顶元素,为$6$。求$7$和$6$的$LCA$:$LCA(7,6)=3$。
+- 发现$LCA(7,6)!=$栈顶元素,进入判断阶段。
+- 判断阶段:发现栈顶节点$6$的Dfs序是大于$LCA(7,6)$的,但是次大节点(栈顶节点下面的那个节点)$1$的Dfs序是小于$LCA$的,说明$LCA$还没有入过栈,所以直接连接$3->6$的边,也就是$LCA$到栈顶元素的边。把$6$从栈中弹出,并且把$LCA(6,7)$入栈。
+- 结束了判断阶段,将$7$入栈,当前栈为$1,3,7$
+- 发现序列里的3个节点已经全部加入过栈了,退出循环。
+- 此时栈中还有3个节点:$1, 3,7$,很明显它们是一条链上的,所以直接链接:$1->3$和$3->7$的边
 - 虚树就建完啦!
 
 其中有很多细节,比如我是用临接表存图的方式存虚树的,所以需要清空临接表。但是直接清空整个临接表是很慢的,所以我们在**有一个从未入栈的元素入栈的时候清空该元素对应的临接表**即可。