如何構建虛樹

如何構建虛樹?

當咱們得到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了。

總之,這個過程看似複雜,但只要想着要始終維護棧的性質(從棧底到棧頂的元素構成虛樹中從上到下的一條鏈)就不容易打錯了。寫的時候能夠畫個圖,讓本身思路清晰

相關文章
相關標籤/搜索