在一棵樹上找到乙個點,把這個點作為樹的根的有根樹,最大子樹的節點數最小。(就是把該點去掉以後,最大連通塊的節點數最小)
1、一棵樹的重心至多有兩個,且相鄰。
2、樹中某個點到所有點到距離之和中,到重心的距離之和是最小的。如果有兩個重心,那麼到它們的距離之和一樣。
3、把兩棵樹用一條邊相連,新樹的重心在原來兩棵樹的重心的連線上。
4、一棵樹新增或刪除乙個結點,重心最多移動一條邊的位置。
通過dfs求出某個點向下的子樹的節點數的大小,在用總節點數減去當前子樹的節點數得到向上的子樹的節點數的大小,再通過定義去求重心。
模版題:poj 1655
1//#include
2 #include3 #include4 #include5 #include6 #include
7 #include8 #include9 #include10 #include11 #include12 #include
13 #include14 #include15 #include16 #include17
#define ll long long
18#define mod 1000000007
19#define inf 0x3f3f3f3f
20#define mem(a,x) memset(a,x,sizeof(a))
21#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
22using
namespace
std;
23const
int maxn = 20005
;24 vectortree[maxn];
25int
minnode,minbalance;
26//
minnode 表示當前的重心
27//
minbalance 表示當前重心下的最大子樹結點個數
28int
d[maxn];
29//
d[i]表示以 i 為根的子樹結點數
30int
n;31
void getcentroid(int u,int
fa)32
42 maxsub=max(maxsub,n-d[u]);
43if(maxsub48int
main()
4957
for(int i=1;i)
63 minnode=0
;64 minbalance=inf;
65 getcentroid(1, 0
);66 printf("
%d %d\n
",minnode,minbalance);67}
68return0;
69 }
樹的重心的性質及其證明
想了我好長時間。樹的重心如果不唯一,則至多有兩個,且這兩個重心相鄰 乙個點是重心,等價於,以這個點為根,它的每個子樹的大小,都不會超過整個樹大小的一半 樹中所有點到某個點的距離和中,到重心的距離和是最小的。如果有兩個重心,那麼到它們的距離和一樣。更進一步,距離和最小與是重心等價 如果乙個樹增添,或刪...
ACM 樹重心的性質及動態維護
本文 求樹重心的方法 nlogn 還記得曾經提到過的樹的 重心 嗎?重心的定義是 以這個點為根,那麼所有的子樹 不算整個樹自身 的大小都不超過整個樹大小的一半。樹的重心的乙個的性質 樹中所有點到某個點的距離和中,到重心的距離和是最小的 如果有兩個重心,那麼他們的距離和一樣。這也是 道路修建 帶來的啟...
求樹的重心
題目 題意 給定一棵樹,求樹的重心的編號以及重心刪除後得到的最大子樹的節點個數size,如果size相同就選取編號最小的.分析 首先要知道什麼是樹的重心,樹的重心定義為 找到乙個點,其所有的子樹中最大的子樹節點數最少,那麼這個點就是這棵 樹的重心,刪去重 心後,生成的多棵樹盡可能平衡.實際上樹的重心...