如何构建虚树

如何构建虚树?

当咱们得到k个关键点后排序

首先把关键点按dfn(即原树的dfs序)从小到大排序top

而后开一个栈block

栈的意义(性质):从栈底到栈顶的元素构成(表示)虚树中从上到下的一条链枚举

虚树构建过程:return

依次枚举关键点x

  • 当栈为空或栈中只有一个元素(即top<=1,top从0开始),直接把x压入栈中(break/return)

  • 不然令lca=LCA(x,stk[top])

    • 若是lca=stk[top]

      ​ 说明x应该接在stk[top]的下面(在虚树中),因此直接把x压入栈中(break/return)

    • 若是lca!=stk[top]

      ​ 说明x和stk[top]分属lca的两棵不一样的子树,并且stk[top]所在的子树中已经构建完成了,因此咱们把lca的stk[top]所在的那棵子树弹栈,在弹栈的过程当中建边(单向边),直到 dfn[stk[top]]<=dfn[lca]<=dfn[stk[top-1]] (即lca在栈顶的两元素的路径上) 或 栈中元素小于2的时候中止弹栈,并判断lca是否等于stk[top]

      • 若不等,先从lca向stk[top]连边,压入lca,再压入x

      • 不然直接压入x

枚举关键点结束后,若栈中的元素超过2个(即top>1),就不断从stk[top-1]向stk[top]连边,并弹出栈顶。

到此,虚树构建完成,而后就能够愉快地DP了。

总之,这个过程看似复杂,但只要想着要始终维护栈的性质(从栈底到栈顶的元素构成虚树中从上到下的一条链)就不容易打错了。写的时候能够画个图,让本身思路清晰

相关文章
相关标签/搜索