dfs树的重心

 

 

#include<iostream>

using namespace std;

int n;

const int N=1e5+10;

int e[N*N],ne[N*N],idx,h[N];//注意要开N*N的大小

bool st[N];//标记数组 标记一下这个节点是否被走过 true即为被走过

 

void add(int a,int b){

e[idx]=b;

ne[idx]=h[a];

h[a]=idx++;

}

int dfs(int u){

int res=0;//存储 删掉某个节点之后,最大的连通子图节点数

st[u]=true;

int sum=1;//存储 以u为根的树 的节点数, 包括u

 

//访问u的每个子节点

for(int i=h[u];i!=-1;i=ne[i]){

int j=e[i];

if(!st[j]){

//如果j节点没有被遍历过

int s=dfs(j);

res=max(s,res);

sum+=s;以j为根的树 的节点数

}

}

res=max(res,n-sum);//选择u节点为重心,最大的 连通子图节点数

ans=min(res,ans);

return sum;//因为sum表示的是以当前节点为根的节点数,如果当前节点没有被遍历过,就会一直递归遍历子节点,直到叶子节点时返回1,然后一直回溯叠加sum就能得到当前节点为根的节点数,而ans是通过比较直接赋值,不需要返回。

//为什么要返回sum?递归要走到头,然后依次返回更新,不返回,统计不了点的个数

}

 

 

int main(){

cin>>n;

for(int i=0;i<n;i++){

int a,b;

cin>>a>>b;

add(a,b),add(b,a);

 

}

dfs(1);

cout<<ans<<endl;

return 0;

}

 

posted @ 2023-03-16 22:16  chenxinyue  阅读(12)  评论(0编辑  收藏  举报