zoukankan      html  css  js  c++  java
  • 洛谷P1122 最大子树和 树形DP

    洛谷P1122 最大子树和
    一道类似树形DP 的题目

    首先我们随意定根 ,假设我们定根为 1,
    那么我们设dp[ i ] 表示 在这个整个以1为根的树中
    以 i为根的子树 i 这个点强制取到 , 我们再从他的子树中
    取出一部分出来,最大能够取到的和

    我们可知 当 枚举到dp[ u ] 时 ,我们看他的儿子取不取
    如果v是它的儿子 若dp[ v ] > 0 那么我们就取 ,
    否则就不取,取了反而会减少
    这样类似最长连续子序列一样就行了
    然后类似树形DP 一样从根节点向根扩展就行了 ,
    也就是dfs下去
    然后用每个点的dp[ i ] 更新 mx就行了 因为这样其实已经包括了
    树的各种形态了
    这个是因为 不管你的树长得多么奇形怪状,他对应到以1 为根的树中
    一定有一个最高点,而这个最高点 就是 根节点

     1 #include <cstdio>
     2 #include <cmath>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <string>
     6 #include <algorithm>
     7 #include <iostream>
     8 #include <iomanip>
     9 using namespace std ; 
    10 
    11 const int maxn = 16011,inf = 1e9  ; 
    12 struct node{
    13     int to,pre ; 
    14 }e[maxn*2];
    15 int n,mx,cnt ; 
    16 int a[maxn],dp[maxn],head[maxn] ; 
    17 
    18 inline int read() 
    19 {
    20     char ch = getchar() ; 
    21     int x = 0 , f = 1 ; 
    22     while(ch<'0'||ch>'9') { if(ch=='-') f = -1 ; ch = getchar() ; } 
    23     while(ch>='0'&&ch<='9') { x = x*10 + ch-48 ; ch = getchar() ; } 
    24     return x * f ; 
    25 }
    26 
    27 inline void add(int x,int y) 
    28 { 
    29     e[++cnt] = (node){ y,head[ x ] } ; 
    30     head[x] = cnt ; 
    31 }
    32 
    33 inline void dfs(int u,int fa) 
    34 {
    35     dp[ u ] = a[ u ] ; 
    36     int v ; 
    37     for(int i=head[ u ];i;i = e[ i ].pre) 
    38     {
    39         v = e[ i ].to ; 
    40         if( v!=fa ) 
    41         {
    42             dfs(v,u) ; 
    43             dp[ u ]+=max(dp[ v ],0) ; 
    44         }
    45     }
    46 }
    47 
    48 int main()
    49 {
    50     n = read() ; 
    51     mx = -inf ; 
    52     for(int i=1;i<=n;i++) 
    53         a[ i ] = read() ; 
    54     int x,y ; 
    55     for(int i=1;i<n;i++) 
    56     {
    57         x = read() ; y = read() ; 
    58         add(x,y) ; add(y,x) ; 
    59     }
    60     
    61     dfs( 1,-1 ) ; 
    62     for(int i=1;i<=n;i++) if( dp[ i ] > mx ) mx = dp [ i ] ;  
    63     printf("%d
    ",mx) ; 
    64     return 0 ; 
    65 }
    66  
  • 相关阅读:
    软工个人阅读作业3
    阅读作业2
    代码复审
    pair project elevator
    读《移山之道——VSTS软件开发指南》
    软件工程作业--词频统计
    个人阅读作业3
    个人阅读作业2
    代码复审
    结对项目电梯吐血总结
  • 原文地址:https://www.cnblogs.com/third2333/p/7100603.html
Copyright © 2011-2022 走看看