1. 程式人生 > 遊戲 >《寶可夢》合作藝術展動畫“時間的漣漪”釋出

《寶可夢》合作藝術展動畫“時間的漣漪”釋出

題目描述

給定一顆樹,樹中包含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;
}