题意

题目链接

Sol

首先一个很显然的思路是直接用\(f[i][j] / g[i][j]\)表示\(i\)的子树中选了\(j\)个节点,该节点是否选的最小权值。但是直接这样然后按照树形背包的套路转移的话会有一种情况无法处理,就是说该节点不选,儿子节点也不选,这样我们就不清楚儿子节点的子节点的贡献了

一种暴力的做法是钦定该节点选,并重新枚举子树中的所有节点,转移出dp值之后背包合并

最后再把\(0\)号节点的合并一次

#include<bits/stdc++.h>
#define chmin(x, y) (x = x < y ? x : y)
#define chmax(x, y) (x = x > y ? x : y)
using namespace std;
const int MAXN = 1001, INF = 2e9 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, K, a[MAXN], dis[MAXN], siz[MAXN], f[MAXN][MAXN], g[MAXN][MAXN], ans;
vector<int> v[MAXN];
void dfs2(int x, int fa, int root) {
f[x][0] = dis[root] * a[x];
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i]; if(to == fa) continue;
dfs2(to, x, root);
for(int j = min(K, siz[x]); ~j; j--)
for(int k = 0; k <= min(j, siz[to]); k++)
chmax(f[x][j], f[to][k] + f[x][j - k]);
}
for(int i = siz[x]; i; i--) chmax(f[x][i], g[x][i]);
}
void dfs(int x, int fa) {
dis[x] += dis[fa]; siz[x] = 1;
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i];
if(to == fa) continue;
dfs(to, x); siz[x] += siz[to];
}
g[x][0] = 0;
memset(f, 0, sizeof(f));
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i]; if(to == fa) continue;
dfs2(to, x, x);
for(int j = min(K, siz[x]); ~j; j--)
for(int k = 0; k <= min(j, siz[to]); k++)
chmax(g[x][j], f[to][k] + g[x][j - k]);
}
for(int i = min(K, siz[x]); i; i--) g[x][i] = g[x][i - 1] + dis[x] * a[x];
}
int main() {
N = read(); K = read();
for(int i = 1; i <= N; i++) {
a[i] = read(); int fa = read(); dis[i] = read();
v[fa].push_back(i);
}
dfs(0, -1);
for(int i = 1; i <= N; i++) ans += dis[i] * a[i];
memset(f, 0, sizeof(f));
int x = 0;
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i];
dfs2(to, x, x);
for(int j = min(K, siz[x]); ~j; j--)
for(int k = 0; k <= min(j, siz[to]); k++)
chmax(f[x][j], f[to][k] + f[x][j - k]);
}
int out = INF;
for(int i = 0; i <= K; i++) out = min(out, ans - f[0][i]);
printf("%d\n", out);
return 0;
}

BZOJ1812: [Ioi2005]riv(树形dp)的更多相关文章

  1. 【BZOJ1812】[Ioi2005]riv 树形DP

    [BZOJ1812][Ioi2005]riv Description 几乎整个Byteland王国都被森林和河流所覆盖.小点的河汇聚到一起,形成了稍大点的河.就这样,所有的河水都汇聚并流进了一条大河, ...

  2. BZOJ 1812: [Ioi2005]riv( 树形dp )

    树背包, 左儿子右兄弟来表示树, dp(x, y, z)表示结点x, x的子树及x的部分兄弟共建y个伐木场, 离x最近的伐木场是z时的最小代价. 时间复杂度O(N^2*K^2) ----------- ...

  3. BZOJ_1812_[Ioi2005]riv_树形DP

    BZOJ_1812_[Ioi2005]riv_树形DP Description 几乎整个Byteland王国都被森林和河流所覆盖.小点的河汇聚到一起,形成了稍大点的河.就这样,所有的河水都汇聚并流进了 ...

  4. bzoj1812 [Ioi2005]riv

    riv 几乎整个Byteland王国都被森林和河流所覆盖.小点的河汇聚到一起,形成了稍大点的河.就这样,所有的河水都汇聚并流进了一条大河,最后这条大河流进了大海.这条大河的入海口处有一个村庄--名叫B ...

  5. bzoj1812 [IOI2005]riv河流

    题目链接 problem 给出一棵树,每个点有点权,每条边有边权.0号点为根,每个点的代价是这个点的点权\(\times\)该点到根路径上的边权和. 现在可以选择最多K个点.使得每个点的代价变为:这个 ...

  6. [bzoj1812][IOI2006]riv_多叉树转二叉树_树形dp

    riv bzoj-1812 IOI-2006 题目大意:给定一棵n个点树,要求在上面建立k个收集站.点有点权,边有边权,整棵树的代价是每个点的点权乘以它和它的最近的祖先收集站的距离积的和. 注释:$1 ...

  7. rivers ioi2005 树形dp

    说句实话,写完这道题,很想吐一口血出来,以示我心情的糟糕: 题目很简单,树形dp,正常做30分钟,硬是做了好几个小时,真是伤心. 题解不写了,只是吐个槽,网上没有用背包写的dp,全是左儿子右兄弟写法, ...

  8. 洛谷P3354 [IOI2005]Riv 河流——“承诺”DP

    题目:https://www.luogu.org/problemnew/show/P3354 状态中要记录一个“承诺”,只需相同承诺之间相互转移即可: 然后就是树形DP的套路了. 代码如下: #inc ...

  9. 1812: [Ioi2005]riv

    1812: [Ioi2005]riv Time Limit: 10 Sec Memory Limit: 64 MB Submit: 635 Solved: 388 [Submit][Status][D ...

随机推荐

  1. [java实现]常见算法之字符串操作

    一.字符串反转 把一个句子中的打次进行反转,比如“how are you” ,变为 “you are how” // 字符串反转 public class StringTest { // 字符反转的方 ...

  2. Centos7.4下安装Nginx

    一.下载Nginx Nginx下载地址:http://nginx.org/en/download.html Nginx是C语言开发的,建议在Linux上运行.由于Nginx的一些模块依赖一些lib,所 ...

  3. linux克隆后修配置

    第一步:克隆 第二步:vi /etc/sysconfig/network-scripts/ifcfg-eth0   编辑 DEVICE=eth0 TYPE=Ethernet ONBOOT=yes NM ...

  4. linux下不同颜色文件的性质

    绿色文件: 可执行文件,可执行的程序 红色文件:压缩文件或者包文件 蓝色文件:目录 白色文件:一般性文件,如文本文件,配置文件,源码文件等 浅蓝色文件:链接文件,主要是使用ln命令建立的文件 红色闪烁 ...

  5. 基础概念——何为GNU与GCC

    GNU:GNU 是一个自由软件操作系统.全称是GNU‘s Not Unix. GNU 是一款类似Unix的操作系统,它所采用的的典型内核是Linux. 该组合叫作GNU/Linux操作系统: GNU网 ...

  6. MyBatis异常总结

    1 Invalid bound statement 1 org.apache.ibatis.binding.BindingException: Invalid bound statement (not ...

  7. Ubuntu 16.04 RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller” 不能上网

    来源:http://forum.ubuntu.org.cn/viewtopic.php?f=116&t=463646 1.执行如下命令 uname -a sudo lspci -knn sud ...

  8. C 标准库 - ctype.h之iscntrl 使用

    iscntrl int iscntrl ( int c ); Check if character is a control character 检查给定字符是否为控制字符,即编码 0x00-0x1F ...

  9. VMware虚拟机配置

    VMware虚拟机配置 背景 在做学习Linux时经常会在win环境下安装虚拟机,这其中涉及到一些细节操作,需要对虚拟机工作模式加以理解. 本文在学习hadoop分布式环境搭建时写作. 1.虚拟交换机 ...

  10. [中英对照]INTEL与AT&T汇编语法对比

    本文首先对文章Intel and AT&T Syntax做一个中英文对照翻译,然后给出一个简单的例子,再用gdb反汇编后,对INTEL与AT&T的汇编语法进行对照从而加深理解. Int ...