树的重心(DFS)

#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<cmath>
using namespace std;
const int maxn=1e5+10;
vector<int>v[maxn];
int subtree[maxn];//表示每点除去自身所对应的子树大小
bool vis[maxn];//用以标记,去重
int n;
void dfs(int father,int node)//father记录node上一步路径来源
{
  for(int i = 0 ; i < v[node].size() ; i++){
  int son=v[node][i];//son为下一步路径方向
  if(son == father){//避开node对应的父亲节点
    continue;
  }
  dfs(node,son);
  if(vis[son] == true)   continue ;//走过son路径
  subtree[node]+=subtree[son];//统计除去node本身的子树大小
  vis[node]=true;//标记
  }
  subtree[node]=max(subtree[node],n-subtree[node]);//去除node节点,保存两棵子树中的最大值
}
int main(){
  memset(subtree,0,sizeof(subtree));
  memset(vis,false,sizeof(vis));
  cin >> n;
  int a,b;
  for(int i = 1 ; i <= n-1 ; i++){
    cin >> a >> b;
    v[a].push_back(b);//无向树
    v[b].push_back(a);
  }
  dfs(0,1);//任意一点开始dfs,1号节点没有父亲,因而father为0
  int res=maxn;int node=0;
  for(int i = 1 ; i <= n; i++){//求出子树最大规模的最小值
    if(subtree[i] < res){
      res=subtree[i];
      node=i;
    }
  }
  cout << node << " " << res << endl;
  return 0;
}

猜你喜欢

转载自www.cnblogs.com/ecustlegendn324/p/11987399.html