1. 程式人生 > >樹的重心

樹的重心

under gif 一點 closed inline pla 所有 isp .net

部分轉載自:http://blog.csdn.net/u013076044/article/details/45915745

定義

找到一個點,其所有子樹中最大的子樹節點數最少,那麽這個點就是整棵樹的重心。

在樹的總點數為偶數時,可能會有兩個重心。

性質

性質 1 :樹中所有點到某個點的距離和中,到重心的距離和是最小的,如果有兩個距離和,他們的距離和一樣。

性質 2 :把兩棵樹通過某一點相連得到一顆新的樹,新的樹的重心必然在連接原來兩棵樹重心的路徑上。

性質 3 :一棵樹添加或者刪除一個節點,樹的重心最多只移動一條邊的位置。

求法

在找樹的重心時,我們先隨意確定一個根,之後通過一遍dfs將所有子樹的大小求出來。

如果有一個點 i 滿足 2 * size[i] >= n ,並且它的兒子都滿足 2 * size[son[i]] <= n ,那麽這個點就是樹的重心。

至於代碼有些不同。

技術分享
 1 inline void dfs(int u)
 2 {
 3     int i, v;
 4     size[u] += 1;
 5     for(i = head[u]; i != -1; i = next[i])
 6     {
 7         v = to[i];
 8         if(v != f[u])
 9         {
10             f[v] = u;
11 dfs(v); 12 size[u] += size[v]; 13 } 14 } 15 if(2 * size[u] >= tot && !ans) ans = u; 16 }
View Code

樹的重心