题意

题目链接

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. day06 --class --home

    # -*- coding: utf-8 -*-# @Time : 2018/12/26 20:29# @Author : Endless-cloud# @Site : # @File : day 06 ...

  2. Centos7.4下安装Nginx

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

  3. Asp.net的生命周期之应用程序生命周期

    参考:http://msdn.microsoft.com/zh-cn/library/ms178473(v=vs.100).aspx 参考:http://www.cnblogs.com/JimmyZh ...

  4. ConcurrentHashMap相关知识点

    ConcurrentHashMap涉及的知识点:HashMap,HashTable,UnSafe,CAS,数组+链表,Segment,ReentrantLock(非公平锁,公平锁),红黑树. 为什么要 ...

  5. Ubuntu16.04安装视觉SLAM环境(DBow3)

    1.从Github上现在DBow3词袋模型库 git clone https://github.com/rmsalinas/DBow3.git 2.开始安装DBow3库,进入DBow3目录 mkdir ...

  6. JSONP-跨域读取数据

    页面代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <tit ...

  7. Go语言容器

    Map 是一种无序的键值对的集合.Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值. Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它.不过,Map 是无 ...

  8. Compile git version inside go binary

    Compile git version inside go binary Abstract 在我们编写的程序中总是希望可以直接查阅程序的版本,通过--version参数就会输出如下版本信息. Buil ...

  9. CSS外边距合并&块格式上下文

    前言问题Margin Collapsing 外边距合并Block Formatting Context 块格式化上下文解决方案参考 前言 之前在前端开发的过程中,都没有遇到外边距合并的问题(其实是因为 ...

  10. mysql中对my.cnf进行说明

    my.cnf说明: #vim /etc/my.cnf以下只列出my.cnf文件中[mysqld]段落中的内容,其他段落内容对MySQL运行性能影响甚微,因而姑且忽略. [mysqld] port =  ...