當前位置:
首頁 >
LCA 最近公共祖先(RMQ、树上倍增、Tarjan),树上两点距离,线段重合长度
發布時間:2024/4/18
42
豆豆
生活随笔
收集整理的這篇文章主要介紹了
LCA 最近公共祖先(RMQ、树上倍增、Tarjan),树上两点距离,线段重合长度
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
對于LCA的一些理解
RMQ
-
dfs處理樹
對于一個樹形結構,可以用dfs將一顆樹轉化成數組,數組中記錄每個點的標號,這樣數組就按照dfs的順序把樹存了下來 -
確定祖先的范圍
對于詢問的節點X和Y, X、Y的祖先一定存在于數組中X、Y第一次出現的區間內,而且祖先就是區間內深度最小的節點 -
RMQ
dfs的復雜度就是樹邊數的二倍,所以區間查詢需要優化,這里可以用RMQ算法,預處理結果O(1)得到最值
樹上倍增
father[ i ] [ j ]表示 i 的第 2 ^ j 個父親
- dfs
dfs在處理深度的同時更新每個人的father數組
- LCA
首先將兩個節點的深度調成一樣,如果深度相同而且是同一個點就找到最近的祖先了,如果深度相同但是節點不同,這時就要向上倍增,需要注意的是倍增的中止條件不是兩個節點相同,而是節點的父親相同。因為每次倍增的范圍很大,很可能超過最近公共祖先,我們可以從最大的祖先開始,如果祖先相同縮小范圍,如果祖先不同更新兩個點的狀態繼續找,最后兩個人的最近公共祖先一定是father[ i ][ 0 ]
Tarjan
完美結合并查集和dfs 在**O(n + q)**解決LCA問題。
dfs的時候需要做以下處理:
- 對于當前點x來說:如果存在詢問(x,y),而且y已經dfs訪問過,那么LCA就是 find(y)
- 回溯的時候要將son的祖先設置為x(子樹的祖先始終為根節點)
求樹上兩點的距離
樹上兩點的距離是唯一的,距離 = depth[X] + depth[Y] - 2 * depth[ancestor]
線段重合的長度
思想和求距離一樣,例如A到C和B到C的重合長度 = (dis_ac + dis_bc - dis_ab)/ 2
int dis(int a, int b) {int ancestor = LCA(a, b);int depth_a = depth[a];int depth_b = depth[b];int depth_ancestor = depth[ancestor];return depth_a + depth_b - 2 * depth_ancestor; }總結
以上是生活随笔為你收集整理的LCA 最近公共祖先(RMQ、树上倍增、Tarjan),树上两点距离,线段重合长度的全部內容,希望文章能夠幫你解決所遇到的問題。