P3047 [USACO12FEB]Nearby Cows G(容斥+dp)
发布日期:2021-06-30 10:20:46 浏览次数:3 分类:技术文章

本文共 1587 字,大约阅读时间需要 5 分钟。

定 义 d o w n [ i ] [ j ] 为 i 为 根 的 子 树 往 下 j 级 儿 子 的 点 权 和 定义down[i][j]为i为根的子树往下j级儿子的点权和 down[i][j]ij

定 义 d p [ i ] [ j ] 表 示 i 在 整 棵 树 中 距 离 j 的 点 权 和 定义dp[i][j]表示i在整棵树中距离j的点权和 dp[i][j]ij

那 么 怎 么 求 d p [ i ] [ j ] ? 那么怎么求dp[i][j]? dp[i][j]?

显 然 d o w n [ i ] [ j ] 是 d p [ i ] [ j ] 的 一 部 分 , 现 在 还 需 要 在 i 上 面 距 离 j 的 显然down[i][j]是dp[i][j]的一部分,现在还需要在i上面距离j的 down[i][j]dp[i][j],ij

u 是 i 的 父 亲 , 那 不 就 是 d p [ u ] [ j − 1 ] 嘛 ? u是i的父亲,那不就是dp[u][j-1]嘛? ui,dp[u][j1]?

但 是 多 算 了 , 多 算 了 d o w n [ v ] [ j − 2 ] 但是多算了,多算了down[v][j-2] ,down[v][j2]

#include 
using namespace std;#define int long longconst int maxn=2e5+10;int n,c[maxn],ans=1e18,sumn,k;struct edge{ int to,nxt;}d[maxn]; int head[maxn],cnt=1;void add(int u,int v){ d[++cnt]=(edge){v,head[u]},head[u]=cnt;}int down[maxn][21],dp[maxn][21];void dfs1(int u,int fa){ down[u][0]=c[u]; for(int i=head[u];i;i=d[i].nxt ) { int v=d[i].to; if( v==fa ) continue; dfs1(v,u); for(int j=1;j<=k;j++) down[u][j]+=down[v][j-1]; }}void DP(int u,int fa){ dp[u][0]=c[u]; for(int i=head[u];i;i=d[i].nxt ) { int v=d[i].to; if( v==fa ) continue; for(int j=1;j<=k;j++) dp[v][j]=dp[u][j-1]+down[v][j]; for(int j=2;j<=k;j++) dp[v][j]-=down[v][j-2]; DP(v,u); }}signed main(){ cin >> n >> k; for(int i=1;i
> l >> r; add(l,r); add(r,l); } for(int i=1;i<=n;i++) cin >> c[i]; dfs1(1,0); for(int i=1;i<=n;i++) for(int x=0;x<=k;x++) dp[i][x]=down[i][x]; DP(1,0); for(int i=1;i<=n;i++) { for(int j=1;j<=k;j++) dp[i][j]+=dp[i][j-1]; cout << dp[i][k] << '\n'; }}

转载地址:https://issue-is-vegetable.blog.csdn.net/article/details/108249869 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:P3205 [HNOI2010]合唱队(区间dp)
下一篇:有源汇上下界最小流[模板]

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年05月01日 07时29分13秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章