趨高智慧機器視覺人工智慧視覺系統的高階統籌與使用
阿新 • • 發佈:2020-10-17
樹的重心
定義
樹上一節點,且滿足它的最大子樹的節點數最小。
性質
\(ps.\) 性質網上都有,但是沒有一篇部落格進行了證明。此後的兒子節點指重心與子樹相連的節點。
\(1.\) 刪除重心後所得的所有子樹,節點數不超過原樹的 \(\frac{1}{2}\),一棵樹最多有 \(2\) 個重心;
證明:這是樹的重心的基本性質,如果重心的一個子樹的節點數大於 \(\frac{1}{2}\) 那麼重心的這個子兒子肯定會比重心更有資格當重心,矛盾。
\(2.\) 樹中所有節點到重心的距離之和最小,如果有兩個重心,那麼他們距離之和相等;
證明:這種情況只有可能是 \(2\) 個重心之間連邊,並且重心 \(1\)
\(3.\) 兩個樹通過一條邊合併,新的重心在原樹 \(2\) 個重心的路徑上;
證明,這個可以用反證法。假設我們取極限情況。一個重心連的最大子樹大小為 \(\frac{n}{2}\),另一個大小為 \(1\)。因為如果新的重心不在 \(2\) 個重心之間,它也會在最大的子樹的兒子節點。那麼此時這個兒子所連的子樹總大小(除了返祖的子樹)為 \(\frac{n - 1}{2}\) 那麼可以可以簡單容斥一下推出返祖的子樹大小為 \(n + 1 - \frac{n - 1}{2}\)
\(4.\) 樹刪除或新增一個葉子節點,重心最多隻移動一條邊;
證明:這個很簡單,因為一個節點被修改最多隻會改變一個子樹的大小。所以重心最多隻能移動一位。
實現
首先是根據他的定義直接用 \(Dfs\) 實現。
int size[maxn], val[maxn], f[maxn];//size[i] 表示 i 的子樹大小,val[i] 表示 i 節點的權值,f[i] 表示 i 為根節點的最大子樹。 void Dfs(int x, int fa) { size[x] = val[x], f[x] = 0; Next(i, x) { int v = e[i].to; if(v == x) continue; Dfs(v, x); size[x] += size[v]; f[x] = max(f[x], size[v]); } f[x] = max(f[x], n - size[now]);//要考慮它父節點引出去的 if(f[x] < f[ans]) ans = x; }