题目大意:
给出N个点,N-1条边,删除一个点后分成至少两棵子树,子树中点最多的那棵就称说它Balance
输出:Balance最小的点,和删除该点后的Balance值
思路:
树形DP
用presum来记录该点前的总点数目
然后用sum来记录包括目前点的总的点数
那么连在同一点的其他子树的点数目就为n-sum-1
然后可得dp[u]={presum,n-sum-1};
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define min(a,b) a<b?a:b
#define max(a,b) a>b?a:b
#define N 20020
#define INF 0x7FFFFFF
vector<int>g[N];
int n;
int dp[N];
int dfs(int u,int pre)
{
int i,sum,t,as;
sum = 0;//总点数
as = 0;
for(i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(v==pre)
continue;
t = dfs(v,u);
sum += t;
as = max(as,t);
}
dp[u]=max(n-sum-1,as);
return sum+1;
}
int main()
{
int T;
int i,j,u,v,node,len;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=0;i<=n;i++)
g[i].clear();
for(i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1,-1);
len=dp[1],node=1;
for(i=2;i<=n;i++)
{
if(dp[i] < len)
{
len = dp[i];
node = i;
}
}
printf("%d %d\n",node,len);
}
return 0;
}