洛谷 P3354 [IOI2005]Riv 河流【树形dp】
...
- 题目:
- 题意:
- 分析:
- 代码:
题目:
传送门
题意:
给出一棵有nnn个节点的树,每条边有一个距离,每个点有一个权值
我们需要选出除根节点以外的kkk个节点,每个点的答案为该点的点权向上直到第一个选出的节点,表示为w∗distw*distw∗dist
求最小的答案
分析:
首先想一想我们需要记录哪些信息:现在在哪个点、这个点的选择如何、到目前为止一共选了几个点
于是有fi,s,kf_{i,s,k}fi,s,k表示现在位于iii,选择状态为sss,在iii的子树中一共选择了kkk个点
但在处理的过程中我发现,这样的状态表示方法看起来没啥问题,但好像答案无法正确的去计算
经过思考,我们发现某一部分的所有答案都会在一个固定的点,即连他们最近的选择的点,所以我们再新增一个状态,表示最近选择的点是哪个
更新状态fi,fa,k&gi,fa,kf_{i,fa,k}\&g_{i,fa,k}fi,fa,k&gi,fa,k表示当前在iii,距离最近被选择的是fafafa,以iii为根的子树内有kkk个点被选择,fff表示不选择iii,ggg表示选择
在处理完一个点的整个子树后因为我们只需最优解,并不刻意iii的选择情况,所以将两个合并成一个就好咯
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define LL long long
using namespace std;
inline LL read()
{LL s=0,f=1; char c=getchar();while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}while(c>='0'&&c<='9') {s=s*10+c-'0';c=getchar();}return s*f;
}
struct node{int to,next,w;
}e[205];
int ls[105],cnt=0;
void add(int x,int y,int w)
{e[cnt]=(node){y,ls[x],w};ls[x]=cnt++;return;
}
int f[105][105][55],g[105][105][55];
int s[105],size=0,dis[105],w[105];
int n=read(),k=read();
void dfs(int u,int fa)
{s[++size]=u;for(int i=ls[u];~i;i=e[i].next){int v=e[i].to;if(fa==v) continue;dis[v]=dis[u]+e[i].w;dfs(v,u);for(int j=1;j<=size;j++)for(int x=k;x>=0;x--){f[u][s[j]][x]+=f[v][s[j]][0];g[u][s[j]][x]+=f[v][u][0];for(int y=1;y<=x;y++){f[u][s[j]][x]=min(f[u][s[j]][x],f[u][s[j]][x-y]+f[v][s[j]][y]);g[u][s[j]][x]=min(g[u][s[j]][x],g[u][s[j]][x-y]+f[v][u][y]);}}}for(int i=1;i<=size;i++){f[u][s[i]][0]+=w[u]*(dis[u]-dis[s[i]]);for(int x=1;x<=k;x++)f[u][s[i]][x]=min(f[u][s[i]][x]+w[u]*(dis[u]-dis[s[i]]),g[u][s[i]][x-1]);}size--;return;
}
int main()
{memset(ls,-1,sizeof(ls));for(int i=1;i<=n;i++){int x=i+1;w[x]=read();int y=read()+1,W=read();add(x,y,W);add(y,x,W);}dfs(1,0);cout<<f[1][1][k];return 0;
}
洛谷 P3354 [IOI2005]Riv 河流【树形dp】相关推荐
- 洛谷P3354 [IOI2005]Riv 河流——“承诺”DP
题目:https://www.luogu.org/problemnew/show/P3354 状态中要记录一个"承诺",只需相同承诺之间相互转移即可: 然后就是树形DP的套路了. ...
- 【bzoj 1812】[Ioi2005]riv(树形dp)
1812: [Ioi2005]riv Time Limit: 10 Sec Memory Limit: 64 MB Submit: 433 Solved: 246 [Submit][Status] ...
- BZOJ.1812.[IOI2005]Riv 河流(树形背包)
BZOJ 洛谷 这个数据范围..考虑暴力一些把各种信息都记下来.不妨直接令\(f[i][j][k][0/1]\)表示当前为点\(i\),离\(i\)最近的建了伐木场的\(i\)的祖先为\(j\),\( ...
- 洛谷P1351 联合权值(树形dp)
题意 题目链接 Sol 一道很简单的树形dp,然而被我写的这么长 分别记录下距离为\(1/2\)的点数,权值和,最大值.以及相邻儿子之间的贡献. 树形dp一波.. #include<bits/s ...
- P3354 [IOI2005]Riv 河流
树形dp,设f[i][j][k]表示第i个点的子树中选择j个点作为伐木场,而且k是建了伐木场的最浅的i的祖先的情况下,最小的收益. 这种题还要练一下,咕咕 然后转移可以n4方做. // luogu-j ...
- 洛谷2015 二叉苹果树 树形DP
https://www.luogu.org/problemnew/show/P2015 二叉苹果树 时间限制: 1 Sec 内存限制: 128 MB 题目描述 有一棵苹果树,如果树枝有分叉,一定是分 ...
- 洛谷 2016 战略游戏(树形DP)
题目描述 Bob喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的办法.现在他有个问题. 他要建立一个古城堡,城堡中的路形成一棵树.他要在这棵树的结点上放置最少数目的士兵,使得这些士兵能 ...
- 洛谷P1122 最大子树和 树形DP初步
小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题.一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的问题.于是当日课后,小明就向老师提 ...
- 洛谷P2016 战略游戏【树形dp】
P2016 战略游戏 时间限制 1.00s 内存限制 125.00MB 题目描述 Bob喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的办法.现在他有个问题. 他要建立一个古城堡,城堡 ...
最新文章
- 前方高能!AI 大牛 LeCun 设想下一个新前沿:摈弃深度学习的所有概率技巧,改而掌握不断转变的能量值...
- 面向对象与面向过程区别
- 局部特征(local feature)
- Http怎么处理长连接
- JUnit4参数化和理论示例
- vb 读取mysql所有表名_vb怎么列举出一个mdb数据库里面所有表名?
- html中%3csvg%3e标签的使用,微信小程序:使用svg
- linux5怎么删除目录,Linux中目录的创建与删除命令使用说明
- 性能优化之页面缓存(以Javascript方式缓存页面部件)
- CCleaner v5.73.8130 发布,系统清理工具
- 单片机C语言程序设计实训100例基于8051+Proteus仿真
- 智头条:萤石拟科创板上市将投18.5亿建厂,Matter智能家居标准延迟至明年,涂鸦、公牛、极米等企业发布
- C#:VARCHART XGantt 5.2.0.167-2022-08-18-UPDATE
- python spss写论文_自从用 spss 写了论文。。。。
- php用代码写的三行情书,三行情书经典语录_最美的三行情书(两行泪,一段情)
- mysql update后可以跟两个表_update后可接两张表吗,
- 关于Http请求GBK乱码转化的问题
- 1023: 大小写转换
- ENVI数据文件打开
- Python运维开发工程师养成记(条件语句)