《寶可夢》合作藝術展動畫“時間的漣漪”釋出
阿新 • • 發佈:2022-02-12
題目描述
給定一顆樹,樹中包含n個結點(編號1~n)和n-1條無向邊。
請你找到樹的重心,並輸出將重心刪除後,剩餘各個連通塊中點數的最大值。
重心定義:重心是指樹中的一個結點,如果將這個點刪除後,剩餘各個連通塊中點數的最大值最小,那麼這個節點被稱為樹的重心。
輸入格式
第一行包含整數n,表示樹的結點數。
接下來n-1行,每行包含兩個整數a和b,表示點a和點b之前存在一條邊。
輸出格式
輸出一個整數m,表示重心的所有的子樹中最大的子樹的結點數目。
資料範圍
1≤n≤105
樣例
輸入樣例
9
1 2
1 7
1 4
2 8
2 5
4 3
3 9
4 6
輸出樣例:
4
DFS(深度優先遍歷)
主要思路:
C++ 程式碼
#include <iostream> #include <cstring> using namespace std; const int N=100010; bool state[N]; //因為是雙向邊 int h[N],e[2*N],ne[2*N],idx,ans=N; int n; int add(int a,int b){ e[idx]=b; ne[idx]=h[a]; h[a]=idx++; } //返回的是以u為根的子樹中點的數量 int dfs(int u){ //標記u這個點被搜過 state[u]=true; //size是表示將u點去除後,剩下的子樹中數量的最大值; //sum表示以u為根的子樹的點的多少,初值為1,因為已經有了u這個點 int size=0,sum=1; for(int i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(state[j]) continue; //s是以j為根節點的子樹中點的數量 int s=dfs(j); // size=max(size,s); sum+=s; } //n-sum表示的是減掉u為根的子樹,整個樹剩下的點的數量 size=max(size,n-sum); ans=min(size,ans); return sum; } int main(){ cin>>n; memset(h,-1,sizeof h); int a,b; for(int i=0;i<n;i++){ cin>>a>>b; add(a,b); add(b,a); } dfs(1); cout<<ans; return 0; }