• BZOJ1131/POI2008 Sta


    题目:Sta

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1131

    题目简介:给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大。

    分析:

      (1)先处理以1为根时树上所有点的深度之和,接着转换根节点。

      (2)转换根节点时,考虑转换根节点的影响:一部分点的深度会减小,一部分点的深度会增加。

      (3)令g[x]表示以x为根时树上所有点的深度之和,f[x]表示x的子树上的节点个数。对于当前根节点v和儿子节点u而言,将当前根节点v更换为子节点u带来的影响:u的子树上的所有节点的深度减少1,其余节点的深度增加1,即g[u]=g[v]-f[u]+n-f[u];

      (4)这道题n的范围有点大,g数组要使用long long 类型,使用DFS可能会栈溢出。

      (5)这道题n的范围有点大,添加读入优化速度有非常大的提高。

    代码:

    我比较懒,没打读入优化。

    递归版:

     1  #include <cstdio>
     2 #define LL long long
     3 LL max=0,ans=0,f0[1000005],f1[1000005],g1[1000005];
     4 int n,size,first[1000005];
     5 struct Edge{int to,next;}e[2000005];
     6 void addedge(int x,int y){
     7     e[++size].to=y;e[size].next=first[x];first[x]=size;
     8     e[++size].to=x;e[size].next=first[y];first[y]=size;
     9 }
    10 void Tree_UP(int fa,int v){
    11     f0[v]=1;
    12     for(int i=first[v],u;i;i=e[i].next){
    13         u=e[i].to;if(u==fa)continue;
    14         Tree_UP(v,u);
    15         f0[v]+=f0[u];
    16         f1[v]+=f1[u]+f0[u];
    17     }
    18 }
    19 void Tree_Down(int fa,int v){
    20     if(g1[v]>max || (g1[v]==max)&&(v<ans)){
    21         max=g1[v];ans=v;
    22     }
    23     for(int i=first[v],u;i;i=e[i].next){
    24         u=e[i].to;if(u==fa)continue;
    25         g1[u]=g1[v]-f0[u]+n-f0[u];
    26         Tree_Down(v,u);
    27     }
    28 }
    29 int main(){
    30     //freopen("in.txt","r",stdin);
    31     //freopen("out.txt","w",stdout);
    32     scanf("%d",&n);
    33     for(int i=1,u,v;i<n;++i){
    34         scanf("%d %d",&u,&v);
    35         addedge(u,v);
    36     }
    37     Tree_UP(-1,1);
    38     g1[1]=f1[1];
    39     Tree_Down(-1,1);
    40     printf("%lld",ans);
    41     //fclose(stdin);fclose(stdout);
    42     return 0;
    43 }

    非递归版:

     1 #include <cstdio>
     2 #define LL long long
     3 LL max=0,f[1000005],g[1000005];
     4 int n,ans,size,first[1000005],q[1000005],fa[1000005];
     5 struct Edge{int to,next;}e[2000005];
     6 void addedge(int x,int y){
     7     e[++size].to=y;e[size].next=first[x];first[x]=size;
     8     e[++size].to=x;e[size].next=first[y];first[y]=size;
     9 }
    10 void Tree_UP(){
    11     int h=1,t=1;q[1]=1;
    12     for(int v;h<=t;++h){
    13         v=q[h];
    14         for(int i=first[v],u;i;i=e[i].next){
    15             u=e[i].to;if(u==fa[v])continue;
    16             fa[u]=v;q[++t]=u;
    17         }
    18     }
    19     for(int v;t;--t){
    20         v=q[t];f[v]=1;
    21         for(int i=first[v],u;i;i=e[i].next){
    22             u=e[i].to;if(u==fa[v])continue;
    23             f[v]+=f[u];
    24         }
    25         g[1]+=f[v];
    26     }
    27 }
    28 void Tree_Down(){
    29     int h=1,t=1;q[1]=1;
    30     for(int v;h<=t;++h){
    31         v=q[h];
    32         if(g[v]>g[ans] || (g[v]==g[ans])&&(v<ans))ans=v;
    33         for(int i=first[v],u;i;i=e[i].next){
    34             u=e[i].to;if(u==fa[v])continue;
    35             q[++t]=u;
    36             g[u]=g[v]-f[u]+n-f[u];
    37         }
    38     }
    39 }
    40 int main(){
    41     //freopen("in.txt","r",stdin);
    42     //freopen("out.txt","w",stdout);
    43     scanf("%d",&n);
    44     for(int i=1,u,v;i<n;++i){
    45         scanf("%d %d",&u,&v);
    46         addedge(u,v);
    47     }
    48     Tree_UP();
    49     Tree_Down();
    50     printf("%d",ans);
    51     //fclose(stdin);fclose(stdout);
    52     return 0;
    53 }
    54 
  • 相关阅读:
    JAVA-初步认识-第七章-默认构造函数
    JAVA-初步认识-第七章-面向对象-构造函数-概述
    JAVA-初步认识-第六章-应用场景
    JAVA-初步认识-第六章-二维数组-另一种定义方式
    JAVA-初步认识-第六章-二维数组-定义方式内存图解2
    JAVA-初步认识-第六章-二维数组-定义方式内存图解
    通过IFeatureClass 接口查询 IWorkspace, 查询通配符
    failed to register esriAddin
    DataGridView实时提交
    ArcGIS AddIn开发笔记(一)
  • 原文地址:https://www.cnblogs.com/hjj1871984569/p/5705877.html
Copyright © 2020-2023  润新知