1. 程式人生 > >Kruskal重構樹

Kruskal重構樹

所有 解決 元素 量化 [] 按秩合並 多次 str 連通

不支持時間旅行的可持久化並查集

  給定 n 個點, 以及 m 次操作, 操作有兩種:

    ① 將點 x 與點 y 進行連邊;

    ② 詢問在前 t 次操作操作中, x 與 y 是否連通.

  n <= 100000, 強制在線.

核心模型

  n 個點, m 條帶權邊的無向圖.

  多次詢問點 x 和點 y 在邊權不超過 w 的邊的作用下的連通性信息(例如, 是否連通).

  強制在線.

  對於不支持時間旅行的並查集問題, 將時間這一維給量化之後, 可以等價地看成這個核心模型.

  對於操作①, 我們相當於連邊 (x, y) , 邊權為 t .

  對於操作②, 相當於查詢邊權不超過 t 的邊的作用下, x 和 y 是否連通.

問題解決

  假如可以離線, 那麽我們就有 Kruskal + 並查集 的做法.

  從小到大, 每連接一條邊, 就將連接下一條邊前的詢問進行回答.

  現在要求在線, 我們嘗試維護歷史版本的並查集.

  我們考慮在並查集存儲更多的信息, 從而也使用更適合的按秩合並的方法, 而不使用更快的路徑壓縮的方法.

  將點 x 的父親設為 y 的時候, 我們考慮多記錄 w 數組, w[x] = 當前連邊的邊權.

  我們當前要查找在不超過 d 的邊權的作用下, x 在並查集的代表元素.

  我們從查詢的點開始跳, 當且僅當 d >= w[x] , 那麽代表元素是 x 的祖先.

  如此下來, 我們能找到並查集的代表元素, 且復雜度為 O(n log n) .

Kruskal重構樹

  我們把利用 f[], w[] 兩個數組構建出來的樹叫做 Kruskal重構樹 .

  我們可以輕易地查詢在邊權不超過 d 的邊的作用下, x 對應的並查集的代表元素 a . 我們還可以知道更多的信息, 因為與 x 連通的元素的集合就是 a 的子樹對應的集合.

  所以, 這棵樹的作用可以概括為: 詢問 x 在邊權不超過 d 的邊的作用下的連通性信息.

  以強制在線 Peaks 一題為例.

  給定一張圖, m 次詢問 (x, k): 在邊權不超過 d 的邊的作用下, 與 x 連通的所有點中點權第 k 小是多少?

  我們考慮利用並查集構建出 Kruskal 重構樹, 我們找邊權不超過 d 的邊的作用下, x 的代表元素 a , 那麽相當於查詢子樹 a 的所有點的點權第 k 小.

Kruskal重構樹