【acwing】846. 树的重心**

穿越隧道

DFS

题意:删掉树中的一个点(及该点的所有边)。
剩下的连通块中,每个联通块中的结点数是多少。
题意要求连不同通块中点的数量的最大值 里面的最小值。

#include 
using namespace std;
const int N = 1e6 + 10;//1e5 + 10,会wa; 可能数据量变大了
int h[N],e[N],ne[N],idx;
int n;
int ans = N;//要找最小的ans,此时给ans赋予一个本题最大的值。
void add(int a,int b){
    e[idx] = b, ne[idx] = h[a],h[a] = idx++;
}
bool st[N];
int dfs(int u){//算以u为根节点的子树中点的数量
    int sum = 1, res = 0;//
    st[u] = true;//访问过的点就不再访问了
    for(int i = h[u]; i != -1; i = ne[i]){
        int j = e[i];
        if(!st[j]){
            int s = dfs(j);//s是以j为根节点中子树结点的数量
            res = max(res,s);//找连通块的子树结点最多的值
            sum += s;//j同样为是u的子树
        }
    }
    res = max(res, n - sum);//和另外的连通块比较
    ans = min(ans,res);
    return sum;
}
int main(){
    cin >> n;
    memset(h,-1,sizeof(h));
    for(int i = 0; i < n - 1; i ++){
        int a,b;
        cin >> a >> b;
        add(a,b);
        add(b,a);
    }
    dfs(1);//随便从哪个点开始搜
    cout << ans << endl;
    return 0;
}

你可能感兴趣的:(acwing,c++,数据结构,搜索)