點分治

  對於要求咱們統計樹上符合條件的路徑信息的問題,咱們通常能夠採用兩種方法來實現,一種是樹上DP,一種就是點分治。點分治更加的簡潔暴力,而樹上DP每每會帶來至關複雜的狀態轉移方程,甚至咱們沒法推出狀態轉移方程。算法

  點分治的核心思想就是枚舉每個頂點並統計通過該頂點的全部路徑信息,而這一過程是經過重構樹來實現的,而且要令重構的樹擁有儘量小的深度以得到更優的性能,換言之,儘量平衡。因爲樹是雙向無環連通圖,對於圖中的任意頂點,咱們都可以將其做爲樹根,從而將圖轉換爲一株樹。那麼應該選擇哪一個結點呢?咱們選擇樹的重心做爲根結點。所謂的樹的重心就是指這樣的一個結點x,全部與其直接相連的子樹的大小(其內包含的結點數目)均不超過整株樹大小的1/2,很顯然一株樹可能存在多個重心,好比只有兩個結點的時候,兩個結點都可以做爲重心。性能

  而對於點分治,咱們接受一株樹,並負責從中找到樹的重心,處理全部通過重心的路徑,以後將重心從樹中移除,此時樹散落爲多株規模更小的樹,爲這些樹遞歸調用點分治的流程,這樣咱們就處理了全部可能的路徑(由於一條路徑必然至少通過一個頂點,而對於任意頂點,咱們都處理了通過它的路徑,因此咱們處理了全部的路徑)。因爲尋找重心和處理通過重心的路徑這一任務的時間複雜度爲線性的,即若是樹的大小爲m,則時間複雜度爲O(m)。而每一層次的遞歸調用,所涉及的全部子樹的大小和始終不超過O(n),n爲原始圖的大小,所以每一層次的時間複雜度均爲O(n),最終的時間複雜度如分治算法同樣取決於遞歸的層次。而因爲移除重心後,全部的子樹大小最大爲原來的一半,而遞歸終止於樹的大小爲1的時候,所以遞歸的層次能夠很容易得出不超過log2(n),總的時間複雜度對應的爲O(nlog2(n))。遞歸

  下面說一下重心的其它性質:重構

  性質1:若是一個結點是樹的重心,則其下最大的子樹的大小必然最小。方法

  證實:假設x是一個含n個結點的樹的重心,對於任意不一樣於x的結點y。咱們發現y必然存在與x下的某株以z爲根的子樹中,而這意味着當以y爲根結點時,以x爲根的子樹的大小T'(x)爲整株樹的大小n減去以z爲根的子樹大小|T(z)|,而因爲x是重心,故T(z)<=n/2,故T'(x)>=n/2,即y的最大子樹的大小至少爲T'(x)=n/2,所以x的最大的子樹的大小必然最小。統計

  性質2:若是一株含n個結點的樹有多個重心,則每一個重心的最大子樹的大小均爲n/2。移動

  證實:由性質1的證實能夠直接得出。時間

  性質3:設樹含n個結點,若u是樹的重心,而v是不一樣於u的樹上的結點,那麼向以v爲根的子樹中追加新的結點,樹的重心將沿着從u到v的簡單路徑移動最多一個結點。遞歸調用

  證實:追加一個結點後,樹的大小變成了n+1,若是u的全部子樹大小依舊保證小於(n+1)/2,那麼u將始終是樹的重心。不然,若u的某個子樹大小超過了(n+1)/2,那麼確定是由包含v的子樹的大小增大致使的,並且很容易發現這株子樹在沒有擴增前的大小應該爲n/2。咱們將重心從u向v移動一個單位後,此時其全部的子樹大小均保證不超過(n+1)/2(此時T'(u)=n-n/2<=(n+1)/2)。枚舉

  性質4:將兩株分別以a與b爲重心的樹A、B經過一條邊(u,v)鏈接起來,那麼新的重心必然處於a到b的簡單路徑上。

  證實:不妨設新的重心落在A上,那麼這等價於向A中結點u所表明的子樹上不斷追加新的結點,由性質3能夠保證A的重心不斷沿着A與結點u之間的路徑不斷移動。而前提已經說明了重心始終落在A上,所以新的重心必然落在A與u之間。而對應的若是新的重心落在B上,那麼新的重心必然處於B與v的簡單路徑上,不管哪一種狀況,都能保證新的重心必定處於a與b的路徑上。

  性質5:一株樹的重心必然存在。

  證實:當樹的大小爲1時,顯然成立,而創建一株樹的過程能夠表示爲向本來只有一個結點的樹追加新的結點,利用性質3提到的算法,沿着某條路徑移動最多一個結點,便可獲得新的重心。而但全部頂點加入完成後,重心也得以確認。

相關文章
相關標籤/搜索