zoukankan      html  css  js  c++  java
  • P1364 医院设置

    医院设置

    又是一道水题。

    洛谷链接

    洛谷上的数据特别水,o(n^3)都能过。

    当然,我是不会用那种暴力枚举的方法的。

    这里要讲的是一种O(n)的做法,对于洛谷那五个数据点,会实现5个0ms。

    大家可以先看一下博客——树的直径及重心,直径没必要看,主要是看重心的求法。

    而这里用的是加权重心,比重心更高级一点的东西。只需把dfs里的size[x]=1改为size[x]=dis[x];把dfs里的size[x]*2>=n改为size[x]*2>=tot就好了(tot是所有点的权值的和)。

    代码:

     1 #include<cstdio>
     2 #define N 420
     3 int next[N],to[N],num,head[N],size[N],dis[N],father[N],deep[N],n,ans,anss,a,b,c,tot;
     4 void add(int false_from,int false_to){
     5     next[++num]=head[false_from];
     6     to[num]=false_to;
     7     head[false_from]=num;
     8 }
     9 int dfs(int x){
    10     size[x]=dis[x];
    11     for(int i=head[x];i;i=next[i])
    12         if(father[x]!=to[i]){
    13             father[to[i]]=x;
    14             dfs(to[i]);
    15             size[x]+=size[to[i]];
    16         }
    17     if(size[x]*2>=tot&&!ans)
    18         ans=x;
    19 }
    20 void dfss(int x){
    21     anss+=(deep[x]-1)*dis[x];
    22     for(int i=head[x];i;i=next[i])
    23         if(!deep[to[i]]){
    24             deep[to[i]]=deep[x]+1;
    25             dfss(to[i]);
    26         }
    27 }
    28 int main(){
    29     scanf("%d",&n);
    30     for(int i=1;i<=n;++i){
    31         scanf("%d%d%d",&a,&b,&c);
    32         dis[i]=a;
    33         tot+=a;
    34         if(b){
    35             add(i,b);
    36             add(b,i);
    37         }
    38         if(c){
    39             add(i,c);
    40             add(c,i);
    41         }
    42     }
    43     dfs(1);
    44     deep[ans]=1;
    45     dfss(ans);
    46     printf("%d",anss);
    47     return 0;
    48 }
    View Code

    当然,这个程序A洛谷没问题,但是搞别的题就需要把数组开大一些了。

  • 相关阅读:
    char和QChar(Unicode的编码与内存里的值还不是一回事)
    ddd
    vim实用笔记
    设计思想
    await使用中的阻塞和并发
    单元测试
    C#简单实现贪吃蛇程序(LinQ + Entity)
    JS逗号、冒号与括号
    C#实现对文件目录的实时监控
    在线预览PDF
  • 原文地址:https://www.cnblogs.com/jsawz/p/6812215.html
Copyright © 2011-2022 走看看