zoukankan      html  css  js  c++  java
  • P3047 [USACO12FEB]Nearby Cows G(树形DP)

    题意:

    给出一棵树。

    对于每个点,求出距离它不超过k的所有点的点权和。

    题解:

    定义(f(i,j))表示第i个点的j范围内的点权和。

    定义(gg(i,j))表示第i个点向下j范围内的点权和。

    (gg(i,j)=c_i+sum_{v in son_u}gg(v,j-1))

    (f(i,j)=f(fa_i,j-1)-gg(i,j-2)+gg(i,j))

    第一遍DFS求出所有的(gg(i,j))

    第二遍DFS求出所有的(f(i,j))

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2e5+100;
    vector<int> g[maxn];
    int a[maxn];
    int n,k;
    int gg[maxn][30];
    int f[maxn][30];
    void dfs1 (int x,int pre) {
    	gg[x][0]=a[x];
    	for (int y:g[x]) {
    		if (y==pre) continue;
    		dfs1(y,x);
    		for (int j=1;j<=k;j++) gg[x][j]+=gg[y][j-1];
    	}
    }
    void dfs2 (int x,int pre) {
    	f[x][0]=gg[x][0];
    	for (int j=1;j<=k;j++) f[x][j]=f[pre][j-1]+gg[x][j];
    	for (int j=2;j<=k;j++) if (pre) f[x][j]-=gg[x][j-2];
    	for (int y:g[x]) {
    		if (y==pre) continue;
    		dfs2(y,x);
    	}
    }
    int main () {
    	cin>>n>>k;
    	for (int i=1;i<n;i++) {
    		int x,y;
    		cin>>x>>y;
    		g[x].push_back(y);
    		g[y].push_back(x);
    	}
    	for (int i=1;i<=n;i++) cin>>a[i];
    	dfs1(1,0);
    	for (int i=1;i<=n;i++) for (int j=1;j<=k;j++) gg[i][j]+=gg[i][j-1];
    	dfs2(1,0);
    	for (int i=1;i<=n;i++) printf("%d
    ",f[i][k]);
    }
    
  • 相关阅读:
    9 与python2交互
    8 内置函数(未完成)
    7 事务
    [转]jquery.vTicker(垂直滚动)
    2015年工作总结(2016-02-02)
    jQuery plugin : jqTransform
    JQuery知识总结
    JQuery事件处理的注意事项
    JQuery基本选择器
    [二]JQueryMobile常用的组件介绍
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/14643819.html
Copyright © 2011-2022 走看看