【bzoj4987】Tree 树形背包dp
题目描述
输入
输出
样例输入
10 7
1 2 35129
2 3 42976
3 4 24497
2 5 83165
1 6 4748
5 7 38311
4 8 70052
3 9 3561
8 10 80238
样例输出
184524
题解
树形背包dp
先考虑几个显而易见的性质:
1.选出的点一定是相邻的
2.对于选出的点,如果从$a_k$再走回$a_1$,那么就相当于每条边经过了两次
由于题目没有包含$dis(a_k,a_1)$,因此就相当于选出的点中的一条链可以只经过一次,其余的需要经过两次。
那我们就可以将选点转化为选边,然后考虑树形背包:
设$f[i][j][k]$表示以$i$为根的子树中选择点$i$,共选出$j$条边,且包含的链端点数目为$k$的最小代价。
这里解释一下:当$k=0$时,相当于要从根节点遍历一遍选出的边然后再从根节点出去;$k=1$时,相当于从根节点遍历一遍,到达某链端点后不出去;$k=2$时相当于从某端点遍历到根节点,然后出去再回来到另一端点。
对于根节点与子节点之间的边,显然当$k=0$或$2$时计算两遍,否则计算一遍。
这里第二维和第三维都满足背包性质,然后就可以树形背包了。
时间复杂度$\Theta(4.5n^2)$
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 3010
using namespace std;
int head[N] , to[N << 1] , len[N << 1] , next[N << 1] , cnt , si[N] , f[N][N][3];
inline void add(int x , int y , int z)
{
to[++cnt] = y , len[cnt] = z , next[cnt] = head[x] , head[x] = cnt;
}
void dfs(int x , int fa)
{
int i , j , k , l , m;
si[x] = 1 , f[x][0][0] = f[x][0][1] = 0;
for(i = head[x] ; i ; i = next[i])
{
if(to[i] != fa)
{
dfs(to[i] , x);
for(j = si[x] - 1 ; ~j ; j -- )
for(k = si[to[i]] - 1 ; ~k ; k -- )
for(l = 2 ; ~l ; l -- )
for(m = l ; ~m ; m -- )
f[x][j + k + 1][l] = min(f[x][j + k + 1][l] , f[x][j][l - m] + f[to[i]][k][m] + len[i] * (2 - (m & 1)));
si[x] += si[to[i]];
}
}
}
int main()
{
int n , k , i , j , x , y , z , ans = 1 << 30;
scanf("%d%d" , &n , &k);
for(i = 1 ; i < n ; i ++ )
scanf("%d%d%d" , &x , &y , &z) , add(x , y , z) , add(y , x , z);
memset(f , 0x3f , sizeof(f));
dfs(1 , 0);
for(i = 1 ; i <= n ; i ++ )
for(j = 0 ; j <= 2 ; j ++ )
ans = min(ans , f[i][k - 1][j]);
printf("%d\n" , ans);
return 0;
}
【bzoj4987】Tree 树形背包dp的更多相关文章
- HDU 1011 树形背包(DP) Starship Troopers
题目链接: HDU 1011 树形背包(DP) Starship Troopers 题意: 地图中有一些房间, 每个房间有一定的bugs和得到brains的可能性值, 一个人带领m支军队从入口(房 ...
- HDU1561 The more ,The better (树形背包Dp)
ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物.但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先 ...
- 【bzoj4007】[JLOI2015]战争调度 暴力+树形背包dp
题目描述 给你一棵 $n$ 层的完全二叉树,每个节点可以染黑白两种颜色.对于每个叶子节点及其某个祖先节点,如果它们均为黑色则有一个贡献值,如果均为白色则有另一个贡献值.要求黑色的叶子节点数目不超过 $ ...
- 【bzoj1495】[NOI2006]网络收费 暴力+树形背包dp
题目描述 给出一个有 $2^n$ 个叶子节点的完全二叉树.每个叶子节点可以选择黑白两种颜色. 对于每个非叶子节点左子树中的叶子节点 $i$ 和右子树中的叶子节点 $j$ :如果 $i$ 和 $j$ 的 ...
- 【bzoj2427】[HAOI2010]软件安装 Tarjan+树形背包dp
题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大).但是现 ...
- 【bzoj4753】[Jsoi2016]最佳团体 分数规划+树形背包dp
题目描述 JSOI信息学代表队一共有N名候选人,这些候选人从1到N编号.方便起见,JYY的编号是0号.每个候选人都由一位编号比他小的候选人Ri推荐.如果Ri=0则说明这个候选人是JYY自己看上的.为了 ...
- [POJ1155]TELE(树形背包dp)
看到这道题的第一眼我把题目看成了TLE 哦那不是重点 这道题是树形背包dp的经典例题 题目描述(大概的): 给你一棵树,每条边有一个cost,每个叶节点有一个earn 要求在earn的和大于等于cos ...
- HDU-4044 树形背包dp好题
不会做,题解是参考网上的.感觉这道题是到好题,使得我对树形背包dp更了解了. 有几个注意的点,直接给出代码,题解以及注意点都在注释里了. #include<bits/stdc++.h> u ...
- poj2486Apple Tree[树形背包!!!]
Apple Tree Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9989 Accepted: 3324 Descri ...
随机推荐
- 我的npm笔记
本文记录一些npm的使用技巧,主要包括自己常用的命令,做个备忘. NPM 是什么? NPM是NodeJS的包管理工具,现在已经进一步发展,致力于为很多其他平台提供包管理工具,其核心思想就是让包的安装更 ...
- MSDN使用
比如我想查一下fopen这个函数怎么用,在索引里搜索一下fopen,很容易找到了. 但是如果我想横向扩展一下,查看一些与fopen相关的函数,应该怎么找呢? 很简单,点击定位: 你就能把fopen定位 ...
- yii框架的中的一些使用介绍
Yii框架的使用整理 获取配置文件中的数据 Yii::$app->params[‘配置文件中对应的参数名称’] 获取文件表单提交的数据 Yii::$app->request->pos ...
- sql备份命令
--将SQL脚本赋值给变量 ) set @SqlBackupDataBase=N'BACKUP DATABASE dbname TO DISK = ''E:\DBBackup\dbname-'+ ), ...
- Java系列之EJB 理解
EJB = Enterprise Java Bean,它和JavaBean有本质的区别,最好不要将他们混淆起来,就像不要将Java和 Javascript混淆起来一样.EJB有3中类型:Session ...
- ES6 随记(1)-- let 与 const
1. const(声明一个只读的常量) 这个是很好理解的,且声明时就必须赋值而不能以后再赋,不然会报错. 而个人认为它最大的用处还是在于 {} 和 [] 上,const 保证了它的内存地址(指针)不变 ...
- Java List 增删改查
定义2个类,课程类和选课类 package com.imooc.collection; /** * 课程类 */ public class Course { private String id; pr ...
- Delphi_添加_mshtml_tlb
1. Delphi --> Component --> Install ActiveX Contol ... --> 选择“Microsoft HTML Object Library ...
- 【转】移动oracle LOB索引到其他表空间
http://blog.chinaunix.net/uid-22948773-id-3451103.html
- js职责链模式
职责链模式(Chain of Responsiblity),使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为 ...