846. 树的重心

注意

ne数组和e数组的大小是顶点数的两倍
每个顶点遍历一遍,搜索中计算和返回。

#include 
#include 
#include 
using namespace std;
const int N = 1e5+5, M = N*2;
bool st[N]={
     false}; 
int h[N], e[M], ne[M];
int idx = 0, n;
int ans = N; //存的是删除每个节点时连通块中最大值最小
void add(int a, int b){
      //邻接表的加边
    e[idx] = b; //idx索引对应的顶点值为b
    ne[idx] = h[a]; //idx的next指针指向h[a]的头索引
    h[a] = idx++; //h[a]的头索引改变了,更新到最新的头索引
}
int dfs(int u){
      //返回每个节点的节点数
    st[u] = true;
    int sum = 1; //当前节点和儿子节点的总节点数
    int res = 0; //每个子连通块的最大值
    for(int i = h[u]; i != -1; i = ne[i]){
     
        int j = e[i]; //从头索引中取出对应顶点的值
        if(!st[j]) {
     
            int s = dfs(j); //儿子节点的节点总数
            res = max(res, s);
            sum += s;
        }
    }
    res = max(res, n - sum);
    ans = min(ans, res);
    return sum;
}
int main(){
     
    int a, b;
    memset(h, -1, sizeof h);
    cin>>n;
    for(int i = 0; i < n-1; i++){
     
        cin>>a>>b;
        add(a, b), add(b, a);
    }
    dfs(1);
    cout<<ans<<endl;
    return 0;
}

邻接表

#include 
#include 
#include 
using namespace std;
const int N = 1e5+5;
bool st[N]; 
int h[N], e[N], ne[N];
int idx = 0;
void add(int a, int b){
      //邻接表的加边
    e[idx] = b; //idx索引对应的顶点值为b
    ne[idx] = h[a]; //idx的next指针指向h[a]的头索引
    h[a] = idx++; //h[a]的头索引改变了,更新到最新的头索引
}
void dfs(int u){
     
    st[u] = true;
    for(int i = h[u]; i != -1; i = ne[i]){
     
        int j = e[i]; //从头索引中取出对应顶点的值
        if(!st[j]) dfs(j);
    }
}
int main(){
     
    int n;
    mesemt(h, -1, sizeof h);
    dfs(1);
    return 0;
}

你可能感兴趣的:(DFS,Tree,AcWing)