BZOJ1812 [IOI2005]river
很常规的一道树规,转为左儿子右兄弟。
然后$f[node][anc][K]$表示在node节点上,最近的有贡献祖先在anc上,在node的儿子和兄弟上有k个有贡献节点的最优值。
然后得出以下转移方程。
$f[node][anc][K]=min\{f[son[node]][anc][k]+f[bro[node]][anc][K-k]\}+Value[node]*(dis[node]-dis[anc])$无贡献
$f[node][anc][K]=min\{f[son[node]][node][k]+f[bro[node]][anc][K-1-k]\}$ 有贡献
下面是代码实现:
//BZOJ 1812
//by Cydiater
//2016.9.5
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <ctime>
#include <cmath>
#include <iomanip>
using namespace std;
#define ll long long
#define up(i,j,n) for(int i=j;i<=n;i++)
#define down(i,j,n) for(int i=j;i>=n;i--)
;
const int oo=0x3f3f3f3f;
inline int read(){
,f=;
;ch=getchar();}
+ch-';ch=getchar();}
return x*f;
}
,fa[MAXN],f[MAXN][MAXN][MAXN],pre_fa[MAXN];
struct edge{
int y,next,v;
}e[MAXN<<];
namespace solution{
inline void insert(int x,int y,int v){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;e[len].v=v;}
void dfs(int node){
for(int i=LINK[node];i;i=e[i].next){
dis[e[i].y]=dis[node]+e[i].v;
dfs(e[i].y);
}
}
void init(){
N=read();K=read();
pre_fa[]=-;
up(i,,N){
Value[i]=read();int y=read(),v=read();
pre_fa[i]=y;
insert(y,i,v);
}
dfs();dis[]=;
}
void build(int node,int father){
int tmp=LINK[node];son[node]=e[tmp].y;fa[node]=father;
if(tmp)build(e[tmp].y,node);node=e[tmp].y;
for(int i=e[tmp].next;i;i=e[i].next){
bro[node]=e[i].y;build(e[i].y,node);
node=e[i].y;
}
}
void TreeDP(int node){
if(son[node])TreeDP(son[node]);
if(bro[node])TreeDP(bro[node]);
int father=pre_fa[node];
){
up(lim,,K)up(k,,lim){
int tmp=Value[node]*(dis[node]-dis[father]);
if(son[node])tmp+=f[son[node]][father][k];
if(bro[node])tmp+=f[bro[node]][father][lim-k];
f[node][father][lim]=min(f[node][father][lim],tmp);
}
up(lim,,K)up(k,,lim){
;
];
if(bro[node])tmp+=f[bro[node]][father][lim-k];
f[node][father][lim]=min(f[node][father][lim],tmp);
}
father=pre_fa[father];
}
){
father=;
up(lim,,K)up(k,,lim){
;
if(son[node])tmp+=f[son[node]][father][k];
if(bro[node])tmp+=f[bro[node]][father][lim-k];
f[node][father][lim]=min(f[node][father][lim],tmp);
}
}
}
void slove(){
build(,-);
memset(f,0x3f,sizeof(f));
TreeDP();
printf(][][K]);
}
}
int main(){
//freopen("input.in","r",stdin);
using namespace solution;
init();
slove();
;
}
BZOJ1812 [IOI2005]river的更多相关文章
- [Ioi2005]River
设f[i][j][k]表示i上游最近的一个伐木场为j且在i所在的子树里共建了k个伐木场(不包含在i的)的最小运费和 设v为u的儿子,dist[u]为u到0号点的距离. 则当i>=j时 f[u][ ...
- bzoj1812 [Ioi2005]riv
riv 几乎整个Byteland王国都被森林和河流所覆盖.小点的河汇聚到一起,形成了稍大点的河.就这样,所有的河水都汇聚并流进了一条大河,最后这条大河流进了大海.这条大河的入海口处有一个村庄--名叫B ...
- [IOI2005]River 河流
题目大意: 给定n个点的有根树,每条边有边权,每个点有点权w, 你要在k个点上建立伐木场,对于每个没有建伐木场的点x,令与它最近的祖先.有伐木场的点,为y,你需要支付dis(x,y)*w[x]的代价. ...
- BZOJ1812: [Ioi2005]riv(树形dp)
题意 题目链接 Sol 首先一个很显然的思路是直接用\(f[i][j] / g[i][j]\)表示\(i\)的子树中选了\(j\)个节点,该节点是否选的最小权值.但是直接这样然后按照树形背包的套路转移 ...
- bzoj1812 [IOI2005]riv河流
题目链接 problem 给出一棵树,每个点有点权,每条边有边权.0号点为根,每个点的代价是这个点的点权\(\times\)该点到根路径上的边权和. 现在可以选择最多K个点.使得每个点的代价变为:这个 ...
- [学习笔记]对未来做出承诺的DP小结
这是一种DP状态设计方法. 有些题,当你必须以一个顺序往后填的话,然而后面的填法会对之前产生影响,那么,不妨在之前就对未来怎么填做出承诺. 通俗的讲,就是对未来打一个表. 然后后面填的时候,直接查表转 ...
- 【BZOJ1812】[Ioi2005]riv 树形DP
[BZOJ1812][Ioi2005]riv Description 几乎整个Byteland王国都被森林和河流所覆盖.小点的河汇聚到一起,形成了稍大点的河.就这样,所有的河水都汇聚并流进了一条大河, ...
- 【BZOJ1812】riv(多叉树转二叉树,树形DP)
题意:给定一棵树,每个点有权值,每条边有边权(单向边).你可以选取K个黑点,使得从每个点移动到距离他最近的黑点的花费(距离*点权)的总和最小. n<=100 k<=50 w[i],a[i] ...
- Moon River
读书笔记系列链接地址http://www.cnblogs.com/shoufengwei/p/5714661.html. 昨晚无意中听到了一首英文歌曲,虽不知其意,但是瞬间就被优美的旋律 ...
随机推荐
- 初用protobuf-csharp-port
下面这个用法是参照protobuf-csharp-port的官方wiki,参见: https://code.google.com/p/protobuf-csharp-port/wiki/Getting ...
- js中递归函数的使用介绍
所谓的递归函数就是在函数体内调用本函数.使用递归函数一定要注意,处理不当就会进入死循环.递归函数只有在特定的情况下使用 ,比如阶乘问题 递归函数是在一个函数通过名字调用自身的情况下构成的,如下所示: ...
- 献给那些每次调试时都要启动很多WEB项目的苦逼程序猿
当一个解决方案包含多个WEB项目的时候,只要按F5调试,其它用不着的WEB项目也会自动添加到托盘里.很多新手都不知道如何解决这个问题,我也是刚知道. 在网上找了很多资料看到有2种解决方法: 1.把WE ...
- android 之 Toast通知的使用
1.默认效果: 代码: Toast.makeText(getApplicationContext(), "默认Toast样式", Toast.LENGTH_SHORT ...
- [转]制作png格式透明图片的简易方法
原文地址:http://blog.csdn.net/zhouyingge1104/article/details/24460743 photoshp之类的专业软件太复杂,其实,制作透明图标有比较简易的 ...
- 【BZOJ 3809】Gty的二逼妹子序列
这个莫队如果用线段树来维护的话,复杂度是$O(n\sqrt{n}logn+qlogn)$ 很明显,可以看出来莫队每次$O(1)$的移动因为套上了线段树变成了$O(logn)$,但莫队移动的总数是非常大 ...
- 几种Aop实现及Castle.DynamicProxy的使用
AoP(Aspect Oriented Programming,面向切面编程) .Net平台AOP技术研究 简单实现 通过继承实现 public interface ICoding { void Do ...
- php实现木桶排序
今天重新看了看木桶排序,思路比较简单,这里整理一下,免得下次忘记. 假设要对一组数据 2 2 3 1 6 5 4 进行桶排序. 1.首先选出最小元素1和最大元素6,做一个桶,也就是定义一个1-6的数组 ...
- 用CSS和jQuery制作简单的下拉框
请选择 百度 谷歌 雅虎 新浪 dowebok 代码 素材 模板 教程 示例下载 // li', function() { var parent = $(this).closest('.select' ...
- Oauth2.0 用Spring-security-oauth2 来实现
前言: 要准备再次研究下 统一认证的功能了,我还是觉得实现统一认证 用Oauth2 最好了,所以,现在再次收集资料和记笔记. 正文: 一.概念理解 OAuth2, 是个授权协议, RFC文档见:htt ...