POJ 1655 POJ 3107 求樹的重心

2021-08-10 10:56:03 字數 1400 閱讀 5959

樹的重心:樹的重心也叫樹的質心。找到乙個點,其所有的子樹中最大的子樹節點數最少,那麼這個點就是這棵樹的重心,刪去重心後,生成的多棵樹盡可能平衡。

換句話說,刪除這個點後最大連通塊(一定是樹)的結點數最小。

刪除1:子樹1:2、6    子樹2:4、5     子樹3:3、7     ans[1]=2;

刪除2:子樹1:6          子樹2:1、3、4、5、7           ans[2]=5;

刪除3:子樹1:7          子樹2:1、2、4、5、6            ans[3]=5;

刪除4:子樹1:5          子樹2:1、2、3、6、7            ans[4]=5;

刪除5:子樹1:1、2、3、4、6、7           ans[5]=6;

刪除6:子樹1:1、2、3、4、5、7           ans[6]=6;

刪除7:子樹1:1、2、3、4、5、6           ans[7]=6;

因此,樹的重心為cnt=min(ans[i],cnt)=2;

poj 1655 

題目大意:給定一棵樹,求樹的重心的編號以及重心刪除後得到的最大子樹的節點個數size,如果有多個重心即size相同就選取編號最小的。

code:

const int maxn=500005;

int tot=0,n;

int ans,size;

int sx[maxn],head[maxn];

int vis[maxn];

struct edge

eg[maxn];

void add(int u,int v)

void init()

void dfs(int u)

}tmp=max(tmp,n-sx[u]);

if(size>tmp||size==tmp&&ans>u)

}int main()

eg[maxn];

int tot=0,num=0,n;

int vis[maxn],sx[maxn],ans[maxn];

int head[maxn];

void add(int u,int v)

int size,cnt;

void dfs(int u)

}tmp=max(tmp,n-sx[u]);

if(tmp

兩個都是模板題,主要還是對樹的重心的理解。簡單的dfs的應用,記錄每次刪除當前結點之後每個子樹的最大節點數,最小化最大節點數就是樹的重心,在一棵樹中,樹的重心可能不止乙個。

POJ 1655 求樹的重心 樹形dp

題目鏈結 樹的重心 若樹上的乙個節點滿足其所有的子樹中最大的子樹節點數最少,那麼這個點就是這棵樹的重心。1.任選乙個點為根,只要統計出每個點的子樹大小,就能很快求出每個點子樹節點的數量的最大值。2.求每個點子樹的大小同樣只需要自底向上的更新資訊。3.記sz u 為子樹u節點的數量 包括 u 本身 4...

poj3107(樹的重心)

求樹的重心。樹的重心是指去掉重心之後剩下的子樹的最大結點個數最少 樹形dp,dp i 表示以i為重心,剩下的子樹的最大結點個數,狀態轉移dp i max dp i siz j 注意用vector超時。如下 include include include include include include...

POJ 3107樹的重心

題意 找樹的重心。定義就是以重心為根的所有子樹裡面最大的最小。做法 瞎dfs一下就行了。記錄一下子樹。重點 這個題vector暴力存邊並不行。水了這麼多水題第一次被卡了。該來的總還是會來。所以用鏈式向前星來模擬鄰接表。比vector速度快的很多,也不難寫。include include includ...