题目描述
几乎整个Byteland王国都被森林和河流所覆盖。小点的河汇聚到一起,形成了稍大点的河。就这样,所有的河水都汇聚并流进了一条大河,最后这条大河流进了大海。这条大河的入海口处有一个村庄——名叫Bytetown。 在Byteland国,有n个伐木的村庄,这些村庄都座落在河边。目前在Bytetown,有一个巨大的伐木场,它处理着全国砍下的所有木料。木料被砍下后,顺着河流而被运到Bytetown的伐木场。Byteland的国王决定,为了减少运输木料的费用,再额外地建造k个伐木场。这k个伐木场将被建在其他村庄里。这些伐木场建造后,木料就不用都被送到Bytetown了,它们可以在运输过程中第一个碰到的新伐木场被处理。显然,如果伐木场座落的那个村子就不用再付运送木料的费用了。它们可以直接被本村的伐木场处理。 注:所有的河流都不会分叉,形成一棵树,根结点是Bytetown。 国王的大臣计算出了每个村子每年要产多少木料,你的任务是决定在哪些村子建设伐木场能获得最小的运费。其中运费的计算方法为:每一吨木料每千米1分钱。 输入输出格式
输入格式:
第一行包括两个数 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村子下游最近的村子(即i村子的父结点)(0≤vi≤n) di——vi到i的距离(千米)。(1≤di≤10000) 保证每年所有的木料流到bytetown的运费不超过2,000,000,000分 50%的数据中n不超过20。 输出格式:
输出最小花费,单位为分。 输入输出样例
输入样例#1:
4 2
1 0 1
1 1 10
10 2 5
1 2 3
输出样例#1:
4

树上分组背包+约定祖先

#include<iostream>
#include<cstdio>
using namespace std; inline int rd() {
int ret=0,f=1;
char c;
while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
while(isdigit(c))ret=ret*10+c-'0',c=getchar();
return ret*f;
} const int MAXN=155; struct Edge {
int next,to,w;
} e[MAXN];
int ecnt,head[MAXN];
inline void add(int x,int y,int w) {
e[++ecnt].next = head[x];
e[ecnt].to = y;
e[ecnt].w = w;
head[x] = ecnt;
} int n,k;
int val[MAXN];
int f[MAXN][MAXN][MAXN];
int g[MAXN][MAXN][MAXN];
int stack[MAXN],top;
int dep[MAXN]; void dfs(int x) {
stack[++top]=x;
for(int i=head[x]; i; i=e[i].next) {
int v=e[i].to;
dep[v]=dep[x]+e[i].w;
dfs(v);
for(int fa=1; fa<=top; fa++) {
for(int j=k; j>=0; j--) {
f[x][j][stack[fa]]+=f[v][0][stack[fa]];
g[x][j][stack[fa]]+=f[v][0][x];
for(int u=0; u<=j; u++) {//
f[x][j][stack[fa]]=min(f[x][j][stack[fa]],f[x][j-u][stack[fa]]+f[v][u][stack[fa]]);
g[x][j][stack[fa]]=min(g[x][j][stack[fa]],g[x][j-u][stack[fa]]+f[v][u][x]);
}
}
}
}
for(int fa=1; fa<=top; fa++) {
for(int j=0; j<=k; j++) {
if(j>=1) f[x][j][stack[fa]]=min(f[x][j][stack[fa]]+val[x]*(dep[x]-dep[stack[fa]]),g[x][j-1][stack[fa]]);
else f[x][j][stack[fa]]+=val[x]*(dep[x]-dep[stack[fa]]);
}
} top--;
} int main() {
n=rd();
k=rd();
for(int i=1; i<=n; i++) {
int y,w;
val[i]=rd();
y=rd();
w=rd();
add(y,i,w);
}
dfs(0);
cout<<f[0][k][0];
return 0;
}

[LUOGU] P3354 [IOI2005]Riv 河流的更多相关文章

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

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

  2. P3354 [IOI2005]Riv 河流

    树形dp,设f[i][j][k]表示第i个点的子树中选择j个点作为伐木场,而且k是建了伐木场的最浅的i的祖先的情况下,最小的收益. 这种题还要练一下,咕咕 然后转移可以n4方做. // luogu-j ...

  3. BZOJ.1812.[IOI2005]Riv 河流(树形背包)

    BZOJ 洛谷 这个数据范围..考虑暴力一些把各种信息都记下来.不妨直接令\(f[i][j][k][0/1]\)表示当前为点\(i\),离\(i\)最近的建了伐木场的\(i\)的祖先为\(j\),\( ...

  4. 【[IOI2005]Riv 河流】

    趁魏佬去英语演讲了,赶快%%%%%%%%%%%%%%魏佬 基本上是照着魏佬的代码写的 这其实还是一个树上背包 我们用\(dp[i][j][k]\)表示在以\(i\)为根的子树里,我们修建\(k\)个伐 ...

  5. [IOI2005]Riv 河流

    https://www.zybuluo.com/ysner/note/1300088 题面 有一棵\(n\)个点的树,现在在上面放\(k\)个标记,使得每个点的权值乘上自己到最近的标记祖先的距离的和最 ...

  6. bzoj1812 [IOI2005]riv河流

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

  7. [IOI2005]Riv河流

    题目链接:洛谷,BZOJ 前置知识:莫得 题解 直接考虑dp.首先想法是设状态 \(dp[u][i]\) 表示u的子树内建 \(i\) 个伐木场且子树内木头都运到某个伐木场的最小花费.发现这样的状态是 ...

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

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

  9. 1812: [Ioi2005]riv

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

随机推荐

  1. 2-17 numpy模块使用

    #CURD import numpy as np data1 = np.array([1,2,3,4,5]) print(data1) data2 = np.array([[1,2], [3,4]]) ...

  2. Maven的-pl -am -amd参数学习

    昨天maven的deploy任务需要只选择单个模块并且把它依赖的模块一起打包,第一时间便想到了-pl参数,然后就开始处理,但是因为之前只看了一下命令的介绍,竟然花了近半小时才完全跑通,故记录此文. 假 ...

  3. P3162 [CQOI2012]组装

    传送门 退火大法好 我并不会正解于是只好打退火了--其他没啥好讲--只要对每一种颜色开一个vector,存一下所有这个颜色的位置,判定的时候可以去所有的颜色里二分找到前缀和后缀,把和当前点距离小的加入 ...

  4. python产生时间

    原来Python在1991年就产生了,google最开始也是两个斯坦福的研究生用Python写的爬虫构建的

  5. CentOS 7静默(无图形化界面)安装Oracle 11g

    准备CentOS 7 系统环境 我以 CentOS-7-x86_64-DVD-1511.iso 为例,简述Oracle 11g的安装过程. 由于是使用静默模式(silent)安装的,无需使用图形化界面 ...

  6. (转载)Python一篇学会多线程

    Python 一篇学会多线程 链接:https://www.cnblogs.com/yeayee/p/4952022.html  多线程和多进程是什么自行google补脑,廖雪峰官网也有,但是不够简洁 ...

  7. Android Dialogs(1)Dialog简介及Dialog分类

    Dialogs A dialog is a small window that prompts the user to make a decision or enter additional info ...

  8. Android中集成第三方支付

    常见的第三方支付解决方案 支付宝支付 微信支付 银联支付 Ping++统一支付平台(需要继承服务器端和客户端) 短信支付 支付宝的集成流程 相关资料链接: 支付宝支付指引流程:支付指引流程 支付宝An ...

  9. 记录一下java在后端用request来判断请求类型

    这几天看代码,看到这么一个操作. String requestType = request.getHeader("X-Requested-With");  于是各种查找   这里记 ...

  10. iOS 中集成海康威视 摄像视频

    本文原文地址  http://www.cnblogs.com/qianLL/p/6652104.html 一.要导入相关的库,注意 这里比较坑的是 要用和他一样的 如果开始的工程中用了AFN或者MJE ...