推薦技術公眾號:不愛睡覺的大豬
好像LCA的題目並不多,現在就做了10道左右,但是找不到別的了,在此做個小總結,將來有更好的題目會不斷更新
解決LCA問題,一般用3種方法
1.朴素方法:兩個點都一直沿路徑往上走,直到有某一個節點被經過兩次並且是第一次出現這樣的點,那么這個就是LCA
此方法最好理解,但是用得不多,但不代表沒作用,有些題目還是需要用到的
2.LCA轉RMQ(在線算法):一般是將LCA轉為RMQ問題,用ST算法求解,當然求解RMQ問題有很多方法,不過ST比較常用而已,這樣做能及時回答每一個詢問
3.Tarjan算法(離線算法):利用Tarjan算法,不過要先讀入所有詢問再一並回答,建議認真學習Tarjan算法本質
******具體問題具體分析,但是可以使用Tarjan算法的時候推薦使用Tarjan算法,代碼量少速度快,另外Tarjan算法容易產生變形,值得深究*************
hdu 2586 How far away ?
模板題,直接求LCA,可以在線,離線算法均可解,可以測試一下模板
poj 1986 Distance Queries
模板題,直接求LCA
hdu 2874 Connections between cities
模板題,不過不是樹是森林,所以某些點不存在LCA,要做判斷
zoj 3195 Design the city
任然算是模板題,上面的題要求兩點間的最短距離,這里要求3點間的最短距離,其實就是兩兩之間求一次LCA並計算出距離,然后相加除以2即可
hdu 3078 Network
LCA + 修改點權值 + 排序:每個點有初始的權值,一邊查詢一邊伴隨着修改某些點的權值,查詢是從a到b路徑中第k大的權值是多少。不需要太多的技巧,修改操作就直接修改,查詢操作先求LCA,然后從a走到b保存下所有的權值,排序,然后直接輸出即可
poj 2763 Housewife Wind
LCA + 修改邊權:一邊查詢兩點間的距離,一邊修改某些邊權。對於修改了某些邊的邊權,就要從此開始遍歷下面的子孫后代更改他們的dir值(點到根的距離)。也不需要太多技巧,直接按題意實現即可,不過時間比較糟糕,用線段樹或樹狀數組可以對修改操作進行優化,時間提升很多
poj 3694 Network
連通分量 + LCA : 先縮點,再求LCA,並且不斷更新,這題用了朴素方法來找LCA,並且在路徑上做了一些操作
poj 3417 Network
LCA + Tree DP : 在運行Tarjan處理完所有的LCA詢問后,進行一次樹DP,樹DP不難,但是要想到用樹DP並和這題結合還是有點難度
poj 3728 The merchant
LCA + 並查集的變形,優化:好題,難題,思維和代碼實現都很有難度,需要很好地理解Tarjan算法中並查集的本質然后靈活變形,需要記錄很多信息(有點dp的感覺)
hdu 3830 Checkers
LCA + 二分:好題,有一定思維難度。先建立出二叉樹模型,然后將要查詢的兩個點調整到深度一致,然后二分LCA所在的深度,然后檢驗