• 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; 
    }
    

      

  • 相关阅读:
    MYSQL的FOUND_ROWS()函数
    mysql连表查询
    mysql事务
    js正则表达式
    mysql关键字执行顺序
    spring aop xml中配置实例
    spring注入bean的五种方式
    【CSS】之选择器性能和规范
    【视频】之H.264
    【Javascript】之eval()
  • 原文地址:https://www.cnblogs.com/guangheli/p/11578035.html
Copyright © 2020-2023  润新知