题意:删除一个节点后,使子树节点数平衡,且子树节点数尽量多,求该节点的编号及子树节点数。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define MAXN 500010
int tot[MAXN],sum[MAXN],son[MAXN],f[MAXN];
namespace Adj{
int size,head[MAXN];
struct node{
int v,next;
}E[2*MAXN];
inline void initAdj(){
size=0;
memset(head,-1,sizeof(head));
}
inline void addAdj(int v,int u){
size++;
E[size].v=v;
E[size].next=head[u];
head[u]=size;
}
}
using namespace Adj;
void dfs(int u)
{
tot[u]=1;
for(int e=head[u];e!=-1;e=E[e].next)
{
if(!tot[E[e].v])
{dfs(E[e].v);
sum[u]+=sum[E[e].v];
if(son[u]<sum[E[e].v])
son[u]=sum[E[e].v];}
}
}
int main()
{
int t,n,m,i,j,k,a,b,pos,ans;
while(scanf("%d",&t)!=EOF)
{
while(t--)
{
initAdj();
memset(son,0,sizeof(son));
memset(tot,0,sizeof(tot));
scanf("%d",&n);
for(i=1;i<n;i++)
{
scanf("%d%d",&a,&b);
addAdj(a,b);addAdj(b,a);
}
for(i=0;i<=n;i++) sum[i]=1;
dfs(1);
pos=1;
ans=son[1];
for(i=2;i<=n;i++)
{
if(ans>max(sum[1]-sum[i],son[i]))
{pos=i;ans=max(sum[1]-sum[i],son[i]);}
}
printf("%d %d\n",pos,ans);
}
}
return 0;
}