BZOJ_1812_[Ioi2005]riv_树形DP

Description

几乎整个Byteland王国都被森林和河流所覆盖。小点的河汇聚到一起,形成了稍大点的河。就这样,所有的河水都汇聚并流进了一条大河,最后这条大河流进了大海。这条大河的入海口处有一个村庄——名叫Bytetown 在Byteland国,有n个伐木的村庄,这些村庄都座落在河边。目前在Bytetown,有一个巨大的伐木场,它处理着全国砍下的所有木料。木料被砍下后,顺着河流而被运到Bytetown的伐木场。Byteland的国王决定,为了减少运输木料的费用,再额外地建造k个伐木场。这k个伐木场将被建在其他村庄里。这些伐木场建造后,木料就不用都被送到Bytetown了,它们可以在 运输过程中第一个碰到的新伐木场被处理。显然,如果伐木场座落的那个村子就不用再付运送木料的费用了。它们可以直接被本村的伐木场处理。 注意:所有的河流都不会分叉,也就是说,每一个村子,顺流而下都只有一条路——到bytetown。 国王的大臣计算出了每个村子每年要产多少木料,你的任务是决定在哪些村子建设伐木场能获得最小的运费。其中运费的计算方法为:每一块木料每千米1分钱。 编一个程序: 1.从文件读入村子的个数,另外要建设的伐木场的数目,每年每个村子产的木料的块数以及河流的描述。 2.计算最小的运费并输出。

Input

第一行 包括两个数 n(2<=n<=100),k(1<=k<=50,且 k<=n)。n为村庄数,k为要建的伐木场的数目。除了bytetown外,每个村子依次被命名为1,2,3……n,bytetown被命名为0。 接下来n行,每行包涵3个整数 wi——每年i村子产的木料的块数 (0<=wi<=10000) vi——离i村子下游最近的村子(或bytetown)(0<=vi<=n) di——vi到i的距离(km)。(1<=di<=10000) 保证每年所有的木料流到bytetown的运费不超过2000,000,000分 50%的数据中n不超过20。

Output

输出最小花费,精确到分。

Sample Input

4 2
1 0 1
1 1 10
10 2 5
1 2 3

Sample Output

4

这题绝对好题,看了https://www.cnblogs.com/CQzhangyu/p/7605481.html后才明白怎么转移的。
设F[i][j][k]表示以i为根的子树中,建了k个伐木场,i的祖先最近的一个建伐木场的位置到i的距离为j。
这样我们把代价提前计算。
转移类似背包,按子树合并,dfs中更新祖先。
F[i][j][k+l]=F[i][j][k]+min(F[son][j][l],F[son][0][l]),分别表示儿子不放/放伐木场。
 
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 205
int head[N],to[N],nxt[N],val[N],w[N],cnt,fa[N][N],siz[N],sf[N],dis[N],g[N][N],m,n;
int f[N][N][N];
inline void add(int u,int v,int z) {
to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; val[cnt]=z;
}
void dfs(int x) {
int i,j,k,l;siz[x]=1;
fa[x][0]=x;
for(i=0;i<=sf[x];i++) {
f[x][i][!i]=(dis[x]-dis[fa[x][i]])*w[x];
}
for(i=head[x];i;i=nxt[i]) {
dis[to[i]]=dis[x]+val[i];
for(j=0;j<=sf[x];j++) fa[to[i]][++sf[to[i]]]=fa[x][j];
dfs(to[i]);
memset(g,0x3f,sizeof(g));
for(j=0;j<=sf[x];j++) {
for(k=min(m,siz[x]);k>=0;k--) {
for(l=min(m-k,siz[to[i]]);l>=0;l--) {
g[j][k+l]=min(g[j][k+l],f[x][j][k]+min(f[to[i]][j+1][l],f[to[i]][0][l]));
}
}
}
siz[x]+=siz[to[i]];
for(j=0;j<=sf[x];j++) {
for(k=min(m,siz[x]);k>=0;k--) {
f[x][j][k]=g[j][k];
}
}
}
}
int main() {
memset(f,0x3f,sizeof(f));
// freopen("riv.in","r",stdin);
// freopen("riv.out","w",stdout);
scanf("%d%d",&n,&m);m++;
int i,z;
for(i=1;i<=n;i++) {
scanf("%d%d%d",&w[i],&fa[i][1],&z);
add(fa[i][1],i,z);
}
dfs(0);
printf("%d\n",f[0][0][m]);
}
/*
4 2
1 0 1
1 1 10
10 2 5
1 2 3
*/ /*
8 2
233 0 5
9 1 80
27 2 20
64 1 100
2 3 14
81 4 5
10 3 70
10 5 8
*/

BZOJ_1812_[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. BZOJ1812: [Ioi2005]riv(树形dp)

    题意 题目链接 Sol 首先一个很显然的思路是直接用\(f[i][j] / g[i][j]\)表示\(i\)的子树中选了\(j\)个节点,该节点是否选的最小权值.但是直接这样然后按照树形背包的套路转移 ...

  4. rivers ioi2005 树形dp

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

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

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

  6. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

  7. COGS 2532. [HZOI 2016]树之美 树形dp

    可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...

  8. 【BZOJ-4726】Sabota? 树形DP

    4726: [POI2017]Sabota? Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 128  Solved ...

  9. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

随机推荐

  1. Rmq Problem

    大视野——3339: Rmq Problem Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1192  Solved: 620[Submit][Sta ...

  2. MySQL 索引及其用法

    一.索引的作用 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,所以查询语句的优化显然是重中之重. 在数据 ...

  3. Go -- 今日头条架构

    夏绪宏,今日头条架构师,专注对高性能大规模 Web 架构,云计算.性能优化.编程语言理论等方向,PHP committer,HHVM 项目贡献者.2009 加入百度,先后从事大规模 IDC 自运维设施 ...

  4. BUPT复试专题—矩阵幂(2012)

    https://www.nowcoder.com/practice/31e539ab08f949a8bece2a7503e9319a?tpId=67&tqId=29638&rp=0&a ...

  5. 从机器码理解RIP 相对寻址

    本作品采用知识共享署名 4.0 国际许可协议进行许可.转载联系作者并保留声明头部与原文链接https://luzeshu.com/blog/rip-relative-addressing 本博客同步在 ...

  6. 生活娱乐 ATM机键盘余温泄露密码

    安全系统存漏洞 ATM机键盘余温或泄露密码 ATM机会泄露你的银行卡密码? 据美国<大众科学>网站8月30日报道,你的手指在ATM机上留下的余温能让尾随你而来的黑客准确获知你的密码. 加利 ...

  7. SAE云平台的使用

    参考文章:http://www.cnblogs.com/luyangsblog/p/3956135.html                 Web开发从零单排之一:在新浪云平台SAE上开发一个htm ...

  8. Redis java使用

    直接应用redis.clients:jedis的jar包到项目中,然后直接就可以使用,具体对五种类型的数据操作方法,可以翻代码找到. 连接到 redis 服务 实例 import redis.clie ...

  9. openwrt procd

    接着前面写过的一篇关于 procd 的笔记. procd 在 STATE_INIT 时会运行 /etc/inittab 中描述的几个级别指定程序. procd_inittab_run("re ...

  10. NPOI实现Excel导入

    导入功能实现: ]; GetExtensionsFromFileStream(file.InputStream); using NPOI.XSSF.UserModel; public List< ...