Sta,题解

题目:

  

分析:

  这个有点过于简单,两次Dfs处理出Dp[i],Son[i],Deep[i],Val[i](分别表示以1为根时i所有子树的深度之和,以1为根时i子树节点个数,以1为根时i深度,以i为根时的)就好了,然后从Val里面找就可以了,复杂度n,直接过掉。这一题时限是10000ms,没错是10000ms,没准常数小一点的nlogn都能过掉,当然好像用不到。

代码:

  

#include <cstdio>
const int maxn=1000000+10;
struct E{
    int to;
    int next;
    E(){
        to=next=0;
    }
}ed[maxn*2];
int head[maxn];
int tot;
void J(int a,int b){
    tot++;
    ed[tot].to=b;
    ed[tot].next=head[a];
    head[a]=tot;
}
int De[maxn];
int er[maxn];
long long Dp[maxn];
int n;
long long val[maxn];
long long ans;
void Dfs1(int x,int fa){
    De[x]=De[fa]+1;
    Dp[x]=De[x];
    for(int i=head[x];i;i=ed[i].next){
        if(ed[i].to==fa)
            continue;
        Dfs1(ed[i].to,x);
        er[x]+=er[ed[i].to]+1;
        Dp[x]+=Dp[ed[i].to];
    }
}
void Dfs2(int x,int fa){
    if(x==1)
        val[x]=Dp[x];
    else
        val[x]=Dp[x]-((long long)De[x]-(long long)1)*((long long)er[x]+(long long)1)+val[fa]-Dp[x]+((long long)De[x]-(long long)2)*((long long)er[x]+(long long)1)+(long long)n-(long long)er[x]-(long long)1;//多转转
    for(int i=head[x];i;i=ed[i].next)
        if(ed[i].to!=fa)
            Dfs2(ed[i].to,x);
}
int main(){
    scanf("%d",&n);
    int js1,js2;
    for(int i=1;i<=n-1;i++){
        scanf("%d%d",&js1,&js2);
        J(js1,js2);
        J(js2,js1);
    }
    Dfs1(1,0);
    ans=Dp[1];
    Dfs2(1,0);
    int js=1;
    for(int i=1;i<=n;i++){
        if(val[i]>ans){
            ans=val[i];
            js=i;
        }
    }
    printf("%d",js);
    return 0;
} 

猜你喜欢

转载自www.cnblogs.com/wish-all-ac/p/12684658.html