题意:一棵树,定义每个节点的balance值:去掉这点节点后的森林里所有树的最大节点数。求出最小的balance值和其所对应的节点编号。
对于删除的每一个点,计算下它的每颗子树的节点数与剩余的子树的节点数,做一下比较。
dp[x][0] 以x节点为根的子树的最大节点数
dp[x][1] 包含x祖先的子树的节点数
注意边界的处理
#include <vector>
#include <cstdio>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 2e4+7;
int n,dp[maxn][2],c[maxn];
vector<int>q[maxn];
void dfs(int x,int fa)
{c[x]=1;dp[x][1]=dp[x][0]=0;int i,f=0;for(i=0;i<q[x].size();i++){int u=q[x][i];if(u==fa) continue;f++;dfs(u,x);c[x]+=c[u];dp[x][0]=max(dp[x][0],c[u]);}if(!f) dp[x][0]=dp[x][1]=n-1;else dp[x][1]=n-c[x];
}
int main()
{int i,t,x,y;scanf("%d",&t);while(t--){scanf("%d",&n);for(i=1;i<=n;i++) q[i].clear();for(i=1;i<n;i++){scanf("%d%d",&x,&y);q[x].push_back(y);q[y].push_back(x);}dfs(1,0);int ans1=0,ans2=INF;for(i=1;i<=n;i++){int temp=max(dp[i][0],dp[i][1]);if(temp<ans2)ans2=temp,ans1=i;}printf("%d %d\n",ans1,ans2);}return 0;
}