求树的重心
给定一棵树,求树的重心的编号以及重心删除后得到的最大子树的节点个数size,如果size相同就选取编号最小的.
首先要知道什么是树的重心,树的重心定义为:找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重
心后,生成的多棵树尽可能平衡
#include <iostream> #include <algorithm> #include <string> #include <string.h> #include <vector> #include <map> #include <stack> #include <set> #include <queue> #include <math.h> #include <cstdio> #include <iomanip> #include <time.h> #include <bitset> #include <cmath> #define LL long long #define INF 0x3f3f3f3f #define ls nod<<1 #define rs (nod<<1)+1 const double eps = 1e-10; const int maxn = 2e4 + 10; const LL mod = 1e9 + 7; int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;} using namespace std; vector<int> vec[maxn]; int siz[maxn],dep[maxn],mx[maxn]; int ans = maxn,id = maxn,cnt,n; void get_size(int x,int f) { siz[x] = 1; for (int i = 0;i < vec[x].size();i++) { int v = vec[x][i]; if (v == f) continue; get_size(vec[x][i],x); siz[x] += siz[vec[x][i]]; cnt = max(cnt,siz[v]); } mx[x] = max(cnt,n-siz[x]); } void get_dep(int x) { for (int i = 0;i < vec[x].size();i++) { dep[vec[x][i]] = dep[x] + 1; get_dep(vec[x][i]); } } //void get_val(int x) { // val[x] = w[x]; // for (int i = 0;i < vec[i].size();i++) { // get_val(vec[x][i]); // val[x] = max(val[x],val[vec[x][i]]); // } //} int main() { int T; scanf("%d",&T); while (T--) { ans = maxn,id = maxn,cnt = 0; memset(siz,0, sizeof(siz)); memset(mx,0, sizeof(mx)); for (int i = 0;i < maxn;i++) vec[i].clear(); scanf("%d",&n); for (int i = 1;i <= n-1;i++) { int u,v; scanf("%d%d",&u,&v); vec[u].push_back(v); vec[v].push_back(u); } get_size(1,0); for (int i = 1;i <= n;i++) { if (mx[i] < ans) { ans = mx[i]; id = i; } } printf("%d %d\n",id,ans); } return 0; }