• luogu 3047 [USACO12FEB]附近的牛Nearby Cows 树形dp


    $k$ 十分小,直接暴力维护 $1$~$k$ 的答案即可. 

    然后需要用父亲转移到儿子的方式转移一下. 

    Code: 

    #include <bits/stdc++.h> 
    #define M 23   
    #define N 100005   
    #define setIO(s) freopen(s".in","r",stdin)            
    using namespace std;            
    int n,K,edges;
    int f[N][M],hd[N],to[N<<1],nex[N<<1],num[N],ans[N][M],sum[N][M];                               
    void addedge(int u,int v) 
    {
        nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;  
    } 
    void dfs(int u,int ff) 
    {                    
        f[u][0]=num[u];      
        for(int i=hd[u];i;i=nex[i]) 
        {
            int v=to[i]; 
            if(v==ff) continue;   
            dfs(v,u);    
            for(int j=1;j<=K;++j) f[u][j]+=f[v][j-1];          
        }      
    }   
    void solve(int u,int ff) 
    {
        ans[u][0]=num[u];       
        ans[u][1]=num[ff]+f[u][1];    
        for(int i=2;i<=K;++i) 
            ans[u][i]=ans[ff][i-1]-f[u][i-2]+f[u][i];      
        for(int i=hd[u];i;i=nex[i]) 
            if(to[i]!=ff) solve(to[i], u);    
    }
    int main() 
    {
        int i,j; 
        // setIO("input"); 
        scanf("%d%d",&n,&K);  
        for(i=1;i<n;++i) 
        {
            int a,b; 
            scanf("%d%d",&a,&b),addedge(a,b),addedge(b,a); 
        }   
        for(i=1;i<=n;++i) scanf("%d",&num[i]); 
        dfs(1,0);          
        for(i=1;i<=n;++i) 
            for(j=1;j<=K;++j) f[i][j]+=f[i][j-1]; 
        for(i=1;i<=K;++i) ans[1][i]=f[1][i];          
        for(int i=hd[1];i;i=nex[i]) solve(to[i], 1);     
        for(i=1;i<=n;++i) printf("%d
    ",ans[i][K]);    
        return 0; 
    }
    

      

  • 相关阅读:
    函数的内置方法
    函数
    文件操作
    三元运算
    流程控制
    集合
    div容器内文本对齐--神奇的css
    Struts2的零配置和rest插件
    MIME类型
    ganymed-ssh2使用
  • 原文地址:https://www.cnblogs.com/guangheli/p/11578035.html
Copyright © 2020-2023  润新知