樹是一種優美的資料結構(嗯嗯,這句話看過百遍了)。
這道題目的描述很清晰,給你一顆n個點(n<10000)有邊權的無根樹,要你統計滿足距離不超過k的點對個數;
因為有多組資料的存在,所以平方的演算法是不行的,便向nlogn靠近(貌似用什麼nb資料結構可以o(n)?天啊。。)。
仔細分析了一下,其實是看了**,對於每個滿足條件的點對,他們之間有一條路徑,對於每乙個點,要麼在這個路徑上,要麼在路徑之外,這就讓我們想到了使用分治演算法:
對於每一顆樹,我們找到最優的這樣乙個根,使得以他兒子為根的子樹中大小最大的最小。這樣選跟是有意義的,可以使得遞迴分下去的層數最少,這樣很容易證明分出的層數是小於等於logn層的(最壞情況一條鏈)。
我們找到這樣的根了,然後只要統計經過他的路徑的條數就可以了,條件就是dep(i)+dep(j)<=k (i和j屬於不同的子樹)—> dep(i)<=k-dep(j),我是利用treap統計的,好像可以o(n)的線性掃瞄,無解。
自己做完後,在遞迴到每顆子樹就可以了。因為一共有logn層,每層要nlogn的統計,所以複雜度是 n log2n 的,速度很快,300ms。
**自我感覺良好:
poj1741(樹上點分治)
題解 樹上分治就是一直找重心,然後計算經過重心點的答案有多少,接著再把重心這個點刪除掉然後接著在對應子樹上接著重複上面步驟直到沒有孩子結點。我是根據下面這篇部落格學習的 include include include include include include include include i...
POJ 1741 樹的分治
題意就是求樹上距離小於等於k的點對有多少個 n2的演算法肯定不行,因為1w個點 這就需要分治。可以看09年漆子超的 本題用到的是關於點的分治。乙個重要的問題是,為了防止退化,所以每次都要找到樹的重心然後分治下去,所謂重心,就是刪掉此結點後,剩下的結點最多的樹結點個數最小。每次分治,我們首先算出重心,...
POJ 1741 樹的分治
tree 求樹上兩點最短距離不超過 k 的對數。通過樹的分治的方法,從根節點自上而下開始求其不同子樹上的兩點通過該點的最短距離小於 k 的對數。有兩點需要注意 1.求某節點不同子樹滿足條件的兩點不好直接求。可以通過先求該節點的所有子節點滿足條件的個數,然後減去其子樹內所有滿足條件的點的個數。這個通過...