【bzoj1131】 [POI2008]Sta

来源:互联网 发布:域名注册购买 编辑:程序博客网 时间:2024/06/05 07:49

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

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;}


原创粉丝点击