树形DP
记f[i]为i子树到i距离和
记g[i]为所有节点到i距离和
DP两次即可
#include<cstdio>
#define N 1000005
#define ll long long
using namespace std;
struct edge{int next,to;}e[N<<1];
int ecnt=1, last[N], siz[N], n, pos;
ll f[N], g[N], mx;
void addedge(int a, int b)
{
e[++ecnt]=(edge){last[a],b};
last[a]=ecnt;
}
void dp1(int x, int fa)
{
siz[x]=1;
for(int i = last[x]; i; i=e[i].next)
{
int y=e[i].to;
if(y==fa)continue;
dp1(y,x);
siz[x]+=siz[y];
f[x]+=f[y]+siz[y];
}
}
void dp2(int x, int fa)
{
if(x!=1)g[x]=g[fa]+n-2*siz[x];
else g[x]=f[x];
if(g[x]>mx)mx=g[x],pos=x;
else if(g[x]==mx && pos>x)pos=x;
for(int i = last[x]; i; i=e[i].next)
{
int y=e[i].to;
if(y!=fa)dp2(y,x);
}
}
int main()
{
scanf("%d",&n);
for(int i = 1; i < n; i++)
{
int a, b;
scanf("%d%d",&a,&b);
addedge(a,b);
addedge(b,a);
}
dp1(1,0);
dp2(1,0);
printf("%d\n",pos);
}