Description
给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大
Input
给出一个数字N,代表有N个点.N<=1000000 下面N-1条边.
Output
输出你所找到的点,如果具有多个解,请输出编号最小的那个.
Sample Input
8
1 4
5 6
4 5
6 7
6 8
2 4
3 4
1 4
5 6
4 5
6 7
6 8
2 4
3 4
Sample Output
7
Solve
树形DP,可以O(1)从父亲转移到儿子
#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
const int N=1000005;
int fi[N],ne[N<<1],j[N<<1],son[N],deep[N];
long long f[N];
int n,m,ans=0;
void dfs1(int ro,int fa){
son[ro]=1;
for (int u=fi[ro];u;u=ne[u]){
if (j[u]==fa)continue;
deep[j[u]]=deep[ro]+1;
dfs1(j[u],ro);
son[ro]+=son[j[u]];
}
}
void dfs2(int ro,int fa){
for (int u=fi[ro];u;u=ne[u]){
if (j[u]==fa)continue;
f[j[u]]=f[ro]-son[j[u]]+n-son[j[u]];
dfs2(j[u],ro);
}
}
int main (){
scanf ("%d",&n);
for (int i=1;i<n;++i){
scanf ("%d%d",&j[i+n],&j[i]);
ne[i]=fi[j[i+n]];fi[j[i+n]]=i;
ne[i+n]=fi[j[i]];fi[j[i]]=i+n;
}
dfs1(1,0);
for (int i=1;i<=n;++i)
f[1]+=deep[i];
dfs2(1,0);
for (int i=1;i<=n;++i)
if (f[i]>f[ans])ans=i;
printf ("%d",ans);
return 0;
}