zoukankan      html  css  js  c++  java
  • NOIP前夕:codevs,修剪花卉

    修剪花卉 
     时间限制: 1 s 空间限制: 256000 KB
    题目描述 Description

    ZZ对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题。

    一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的问题。

    于是当日课后,ZZ就向老师提出了这个问题:

    一株奇怪的花卉,上面共连有N 朵花,共有N-1条枝干将花儿连在一起,并且未修剪时每

    朵花都不是孤立的。

    每朵花都有一个“美丽指数”,该数越大说明这朵花越漂亮,也有“美丽指数”为负数的,

    说明这朵花看着都让人恶心。

    所谓“修剪”,意为:去掉其中的一条枝条,这样一株花就成了两株,扔掉其中一株。

    经过一系列“修剪“之后,还剩下最后一株花(也可能是一朵)。

    老师的任务就是:通过一系列“修剪”(也可以什么“修剪”都不进行),使剩下的那株(那

    朵)花卉上所有花朵的“美丽指数”之和最大。

    老师想了一会儿,给出了正解(交大的老师是很牛的~)。ZZ见问题被轻易攻破,相当不爽,

    于是又拿来问你。

    输入描述 Input Description

    第一行一个整数N(1 ≤ N ≤ 16000)。表示原始的那株花卉上共N 朵花。

    第二行有N 个整数,第I个整数表示第I朵花的美丽指数。

    接下来N-1行每行两个整数a,b,表示存在一条连接第a 朵花和第b朵花的枝条。

    输出描述 Output Description

    一个数,表示一系列“修剪”之后所能得到的“美丽指数”之和的最大值。保证绝对值不超

    过2147483647。

    样例输入 Sample Input

    7

    -1 -1 -1 1 1 1 0

    1 4

    2 5

    3 6

    4 7

    5 7

    6 7

    样例输出 Sample Output
    3
    数据范围及提示 
    Data Size & Hint
    数据范围:
    对于 60%的数据, 保证N≤1,000
    对于100%的数据,保证N≤16,000


    树形dp
    f[i]:=sigma(max(0,f[son[i]]))+init[i]
    code:
    type rec=record
             x,y:longint;
             end;
    
    var n:longint;
        i,j,k:longint;
        max:longint;
        init:array[1..16000]of longint;
        edge:array[1..32000]of rec;
        num1,num2:array[1..16000]of longint;
        used:array[1..16000]of boolean;
        f:array[1..16000]of longint;
        num:longint;
        x,y:longint;
    
    procedure qsort(x,y:longint);
              var head,tail,k:longint;
                  temp:rec;
              begin head:=x; tail:=y;
                    k:=edge[(head+tail) div 2].x;
                    while head<tail do
                          begin while edge[head].x<k do inc(head);
                                while k<edge[tail].x do dec(tail);
                                if head<=tail
                                   then begin temp:=edge[head];
                                              edge[head]:=edge[tail];
                                              edge[tail]:=temp;
                                              inc(head);
                                              dec(tail);
                                        end;
                          end;
                    if head<y then qsort(head,y);
                    if x<tail then qsort(x,tail);
              end;
    
    procedure dfs(x:longint);
              var i,j,k:longint;
                  xxx:longint;
              begin f[x]:=init[x];
                    xxx:=0;
                    for i:=1 to num2[x] do
                        if used[edge[num1[x]+i-1].y]
                           then begin k:=edge[num1[x]+i-1].y;
                                      used[k]:=false;
                                      inc(xxx);
                                      dfs(k);
                                      if f[k]>0
                                         then f[x]:=f[x]+f[k];
                                end;
                    if (xxx=0)
                       then begin if (init[x]<0)
                                     then f[x]:=0
                                     else f[x]:=init[x];
                            end;
              end;
    
    begin readln(n);
          num:=0;
          for i:=1 to n do
              read(init[i]);
          for i:=1 to n-1 do
              begin inc(num);
                    readln(x,y);
                    edge[num].x:=x;
                    edge[num].y:=y;
                    inc(num);
                    edge[num].x:=y;
                    edge[num].y:=x;
              end;
          qsort(1,num);
          fillchar(num1,sizeof(num1),0);
          fillchar(num2,sizeof(num2),0);
          for i:=1 to n do
              num1[i]:=maxlongint;
          for i:=num downto 1 do
              begin inc(num2[edge[i].x]);
                    if num1[edge[i].x]>i
                       then num1[edge[i].x]:=i;
              end;
          fillchar(used,sizeof(used),true);
          fillchar(f,sizeof(f),0);
          used[i]:=false;
          dfs(i);
          max:=f[1];
          for i:=2 to n do
              if max<f[i]
                 then max:=f[i];
          writeln(max);
    end.
  • 相关阅读:
    linux内核中的crng是什么?
    linux内核中的hisi_sas是什么?
    linux内核中的brd是什么?
    内核中的xenfs是什么?
    linux内核中的cfq输入输出调度算法
    linux内核中的最简单的输入输出调度算法noop
    linux内核中侧async_tx是什么?
    linux内核中的fuse是什么?
    Executors.newSingleThreadScheduledExecutor();线程池中放入多个线程问题
    Executors.newSingleThreadScheduledExecutor() 问题
  • 原文地址:https://www.cnblogs.com/spiderKK/p/4928490.html
Copyright © 2011-2022 走看看