模板:
//数组表示邻接表
int top=0;//向--点中存第top个边
int head[MAX_N]=-1;//每个点在建立邻接表时,栈顶的边的编号
//边的结构体
struct Edge{
int v;//另一端连接的点
int next;//栈中 下面 一条边的编号
}e[MAX_E];
void add(int u,int v){
e[top].v=v;
e[top].next=head[u];
head[u]=top++;//top为要加入边的编号,更新后为下一次的加入做准备,除此之外不用这个变量
//但是注意,head[u]仍然指向栈顶的第一条边,因为是top++嘛 ,还是分两步写吧
}
void dfs(){
for(int i=0;i<n;i++){//遍历所有的点
//j=head[i]:获取当前邻接表的栈顶边的编号
//j=e[j].next:获取栈中下一条边的编号,j==-1表示遍历完
for(int j=head[i];j!=-1;j=e[j].next ){
}
}
}
//dfs可以很好的算出每颗子树的大小
//树的重心
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e5+10;
const int M=2*N;
int book[N];
int top=0;
int head[N];
struct Edge{
int v;
int next;
}e[M];
int n;
int ans=N;//
void add(int u,int v){
e[top].v =v;
e[top].next =head[u];
head[u]=top++;
}
//返回的是以u为根 的子树的大小
int dfs(int u){
int res=0;//删掉u之后,最大的连通子图节点数
int size_u=1;//初始化是1
book[u]=1;
for(int j=head[u];j!=-1;j=e[j].next ){
int t=e[j].v;
if(book[t]==0){
int s=dfs(t);//递归,,u子树的大小
res=max(res,s);
size_u+=s;
}
}
res=max(res,n-size_u);//size_u在这里用到
ans=min(ans,res);
return size_u;
}
int main(){
//所以之前的模板是错的,要用memset
memset(head,-1,sizeof head);
memset(book,0,sizeof book);
cin>>n;
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;
}
yeah~~~~