這個知識點好像咕咕咕了好長了。。趁還沒退役趕緊補一下吧。。
講的非常簡略,十分抱歉。。
前置知識
Kruskal算法
一定的數據結構基礎(如主席樹)
Kruskal重構樹
直接bb好像不是很好講,那就從這道題入手吧。
在Bytemountains有$N$座山峰,每座山峰有他的高度$h_i$。
有些山峰之間有雙向道路相連,共$M$條路徑,每條路徑有一個困難值,這個值越大表示越難走.
現在有$Q$組詢問,每組詢問詢問從點$v$開始只經過困難值小於等於$x$的路徑所能到達的山峰中第$k$高的山峰,如果無解輸出$-1$
首先,這是一張圖(你在說大實話么)
對於一個點來說,經過困難值小於等於$x$的路徑所能到達的點是一定的。
但是這和生成樹有啥關系呢?
顯然,若一個點能通過一條路徑到達,那么我們走最小生成樹上的邊也一定能到達該節點。
這樣我們把最小生成樹建出來,就可以少考慮很多邊了。
然而並沒有什么卵用。。
現在我們需要做的,是找一種方法,能夠維護出一個點能到達的點。
於是Kruskal重構樹就誕生了。
它的思想是這樣的:
在運行Kruskal算法的過程中,對於兩個可以合並的節點$(x, y)$,斷開其中的連邊,並新建一個節點$T$,把$T$向$(x, y)$連邊作為他們的父親,同時把$(x, y)$之間的邊權當做$T$的點權
比如說
重構之后是這樣的:
這樣我們得到了一個新的樹,考慮它有什么性質。
其中最重要的一條就是:一個節點能走到的節點一定在它的子樹中
然后這道題就做完了,直接dfs序+主席樹即可
當然,除了這一條之外,Kruskal重構樹還有很多有意思的性質
- 是一個二叉樹
- 如果是按最小生成樹建立的話是一個大根堆(important!)
- 任意兩個點路徑上邊權的最大值為它們的LCA的點權
例題