『树形DP』[IOI2005]Riv 河流
题目描述
题解
我们设f[x][j][k]f[x][j][k]f[x][j][k]表示运输完了以xxx为根的子树,iii的祖先jjj建立了伐木场,建立了kkk个伐木场的最小运输代价。由于题目中说明了0号点一定要建立伐木场,故结果是f[0][0][K].f[0][0][K].f[0][0][K].
我们可以将这道题拆分成两部分,我们另f数组表示在当前状态下,不选择选择iii的最小花费;ggg数组表示选择节点iii。有与f[x][j][k]f[x][j][k]f[x][j][k]中的jjj树xxx的祖先,因此我们用一个栈记录节点xxx的父亲即可。这里记为fa=stack[j]fa=stack[j]fa=stack[j],用jjj枚举。
因为我们需要求出的时子树的答案,用f[x]f[x]f[x]表示已经不选择xxx的的,g[x]g[x]g[x]表示已经选择xxx的。但是我们对于子树的选与不选是不在乎的,我们可以对子树的fff和ggg值进行合并,那么就可以得到当前的fff和ggg的状态转移方程了:
f[x][fa][k]=min(f[x][fa][k],f[x][fa][k−t]+f[y][fa][t])g[x][fa][k]=min(g[x][fa][k],g[x][fa][k−t]+f[y][x][t])f[x][fa][k] = \min(f[x][fa][k],f[x][fa][k-t]+f[y][fa][t])\\ g[x][fa][k] = \min(g[x][fa][k],g[x][fa][k-t]+f[y][x][t])f[x][fa][k]=min(f[x][fa][k],f[x][fa][k−t]+f[y][fa][t])g[x][fa][k]=min(g[x][fa][k],g[x][fa][k−t]+f[y][x][t])
一些小解释:
- 对于ggg的求解,子树必然以xxx为根最优。
- ggg都已经选择自己了,为什么还要有fafafa这个状态呢?因为就算选择了自己,fafafa这个状态还是要有的,为未来的转移做铺垫。和fff来做一个对应。
一些小细节:在转移状态的时候一定要先随便赋值一个未来的状态之一,这样才能在未来的状态中取最小值;否则在实现上就不会选取子树的答案了。
然后考虑合并fff和ggg的方案:
f[x][fa][k]=min(f[x][fa][k]+w[x]∗(dep[x]−dep[fa]),g[x][fa][k−1])f[x][fa][k] = min(f[x][fa][k]+w[x]*(dep[x]-dep[fa]),g[x][fa][k-1])f[x][fa][k]=min(f[x][fa][k]+w[x]∗(dep[x]−dep[fa]),g[x][fa][k−1])
前者好说,后者为什么要减去111呢?因为选来就算选了kkk个伐木站,在状态转移方程中是不把节点xxx选进去的。因此我们需要减去111来空出这个位置。
代码
#include <bits/stdc++.h>
#define int long longusing namespace std;
const int N = 200;int n, K;
int top = 0;
int Stack[N], dep[N], g[N][N][N], f[N][N][N], w[N];vector < pair<int,int> > a[N];void dfs(int x,int fa)
{Stack[++top] = x;for (int i=0;i<a[x].size();++i){int y = a[x][i].first;int v = a[x][i].second;if (y == fa) continue;dep[y] = dep[x] + v, dfs(y,x);for (int j=1;j<=top;++j){int fa = Stack[j];for (int k=K;k>=0;--k){f[x][fa][k] += f[y][fa][0];g[x][fa][k] += f[y][x][0];for (int t=0;t<=k;++t){f[x][fa][k] = min(f[x][fa][k],f[x][fa][k-t]+f[y][fa][t]);g[x][fa][k] = min(g[x][fa][k],g[x][fa][k-t]+f[y][x][t]);}}}}for (int j=1;j<=top;++j){int fa = Stack[j];for (int k=0;k<=K;++k){if (k) f[x][fa][k] = min(f[x][fa][k]+w[x]*(dep[x]-dep[fa]),g[x][fa][k-1]);else f[x][fa][k] = f[x][fa][k]+w[x]*(dep[x]-dep[fa]);}}top --;
}signed main(void)
{freopen("riv.in","r",stdin);freopen("riv.out","w",stdout);cin>>n>>K;for (int i=1;i<=n;++i){int fa,dis;cin>>w[i]>>fa>>dis;a[i].push_back(make_pair(fa,dis));a[fa].push_back(make_pair(i,dis));}dfs(0,-1);cout<<f[0][0][K]<<endl;return 0;
}
『树形DP』[IOI2005]Riv 河流相关推荐
- 『树上匹配 树形dp』
树上匹配 Description 懒惰的温温今天上班也在偷懒.盯着窗外发呆的温温发现,透过窗户正巧能看到一棵 n 个节点的树.一棵 n 个节点的树包含 n-1 条边,且 n 个节点是联通的.树上两点之 ...
- 洛谷P3354 [IOI2005]Riv 河流——“承诺”DP
题目:https://www.luogu.org/problemnew/show/P3354 状态中要记录一个"承诺",只需相同承诺之间相互转移即可: 然后就是树形DP的套路了. ...
- 『树形DP·换根法』Accumulation Degree
题目描述 有一个树形的水系,由 N-1 条河道和 N 个交叉点组成. 我们可以把交叉点看作树中的节点,编号为 1~N,河道则看作树中的无向边. 每条河道都有一个容量,连接 x 与 y 的河道的容量记为 ...
- P3354 [IOI2005]Riv 河流
树形dp,设f[i][j][k]表示第i个点的子树中选择j个点作为伐木场,而且k是建了伐木场的最浅的i的祖先的情况下,最小的收益. 这种题还要练一下,咕咕 然后转移可以n4方做. // luogu-j ...
- 洛谷 P3354 [IOI2005]Riv 河流【树形dp】
... 题目: 题意: 分析: 代码: 题目: 传送门 题意: 给出一棵有nnn个节点的树,每条边有一个距离,每个点有一个权值 我们需要选出除根节点以外的kkk个节点,每个点的答案为该点的点权向上直到 ...
- BZOJ.1812.[IOI2005]Riv 河流(树形背包)
BZOJ 洛谷 这个数据范围..考虑暴力一些把各种信息都记下来.不妨直接令\(f[i][j][k][0/1]\)表示当前为点\(i\),离\(i\)最近的建了伐木场的\(i\)的祖先为\(j\),\( ...
- [IOI2005]Riv 河流
题目描述 几乎整个Byteland 王国都被森林和河流所覆盖.小点的河汇聚到一起,形成了稍大点的河.就这样,所有的河水都汇聚并流进了一条大河,最后这条大河流进了大海.这条大河的入海口处有一个村庄--B ...
- [IOI2005]Riv河流
题目链接:洛谷,BZOJ 前置知识:莫得 题解 直接考虑dp.首先想法是设状态 \(dp[u][i]\) 表示u的子树内建 \(i\) 个伐木场且子树内木头都运到某个伐木场的最小花费.发现这样的状态是 ...
- Luogu P3354 [IOI2005]Riv河流 题解———再加一维!再加一维!
Description n≤100,k≤min(n,50)n≤100,k≤min(n,50)n≤100,k≤min(n,50). Solution 考虑树形dpdpdp. 状态设计为dpi,jdp_{ ...
最新文章
- phpexcel导出超过26列解决方案
- 【怎样写代码】确保对象的唯一性 -- 单例模式(四):饿汉式单例类与懒汉式单例类的讨论
- 如何在IE右键菜单中添加菜单项(转)
- 老鼠之Atlas之旅(一):Atlas官方站点
- Feature Schema中Module和File节点属性含义的解释
- 鸿蒙系统开发大会怎么参加,鸿蒙2.0来了?华为将举行开发者大会,做自己的手机系统!...
- shell脚本参数中有空格
- 祥林嫂形容哪类人?祥林嫂比喻什么样的人物?
- XidianOJ 1175: count
- Windows 下缺少依赖库问题解决
- 蛋白质配体复合物-分子动力学模拟Gromacs
- E680最强综合技巧集合
- Nessus下载及安装
- 厦门大学计算机专业录取分数线2019,厦门大学录取分数线2019年各省及各专业分数线...
- 影创科技助力云南首例MR混合现实肝脏手术成功实施
- 《项目管理知识体系指南》(PMBOK®指南)第3 版
- 奉主耶稣基督的名,斥责一切魔鬼撒旦黑暗势力对我的捆绑,斥责一切邪灵对我的束缚,仇敌必然逃跑
- Kaggel Egg脑电图像癫痫预测——资料整理
- 【C++】《披着clion的外衣实则在讲cmake》的知识点目录
- 微信小程序之获取skey保持登陆状态
热门文章
- oracle spool循环导出文件,oracle 使用spool导出数据到文件
- 为什么建议大家使用 Linux 开发?爽!!!!!!!
- 计算机辅助设计软件应用答案,专科《计算机辅助设计软件的应用》试卷答案.doc...
- flash服务器停止响应,shockwave flash 未响应解决方法,shockwave flash已经崩溃解决方法...
- matlab等式操作,等式和等式约束
- c语言----移动n根火柴使等式成立
- word表格分开快捷键_在Word 表格的编辑中,快速拆分表格应按快捷键为______。
- 【UI设计No7】单页
- 计算机毕业设计基于Android宠物领养救助系统app——计算机毕业设计
- zhong yu gong si