UVA Live Archive 4015 Cave (树形dp,分组背包)
和Heroes Of Might And Magic 相似,题目的询问是dp的一个副产物。
距离是不好表示成状态的,但是可以换一个角度想,如果知道了从一个点向子树走k个结点的最短距离,
那么就可以回答走x距离能访问到的最大结点数量。
当访问了一棵子树,想要访问子树外的结点时,一定要先从子树的根结点出来。
状态可以定义为dp[u][k][?],u表示根节点,k表示访问u的k个子结点,?的取值为0和1表示 不回到u 和 回到u。
不难想到转移过程:
dp[u][k][0] <- dp[u][a][1] + dp[v][b][0] 或 dp[v][b][1] + dp[u][a][0]
dp[u][k][1] <- dp[u][a][1] + dp[v][b][1]
k = a+b+1, v 是 u的子节点
边界为 dp[u][0][0] = dp[u][0][1] = 0表示停留在u.
困难的是转移的顺序,必须保证重复走一个结点只算一次,
实际计算的时候我们只能一个一个的枚举v,对于枚举到v的结点数量b只能从没有考虑过v结点的状态转移。
把结点数量看出物品,v的结点数实际上是一组物品,不能同时选。
剩下和分组背包差不多。
#include<bits/stdc++.h>
using namespace std; #define PS push const int maxn = ;
const int INF = 0x3f3f3f3f; int hd[maxn], nx[maxn], to[maxn], ec;
void add(int u,int v)
{
to[ec] = v;
nx[ec] = hd[u];
hd[u] = ec++;
} int fa[maxn], dist[maxn], deg[maxn], sz[maxn];
int ks;
int n; int dp[maxn][][maxn]; int sol()
{
queue<int> q;
for(int i = ; i < n; i++){
if(!deg[i]) { q.PS(i); }
}
int u;
while(q.size()){
u = q.front(); q.pop();
sz[u] = ;
dp[u][][] = dp[u][][] = ;
for(int i = hd[u]; ~i; i = nx[i]){
int v = to[i];
sz[u] += sz[v];
for(int k = sz[u]-sz[v]; k < sz[u]; k++) dp[u][][k] = dp[u][][k] = INF;
for(int k = sz[u]-; k > ; k--){//从大到小枚举k 保证是上一组的状态转移过来
for(int a = min(sz[v],k)-; a >= ; a--){//先枚举k,然后枚举物品保证组内物品不会同时选到
int b = k--a;
//知道dp[v][b][0] 和 dp[v][b][1] 以后新增加的路径
dp[u][][k] = min(dp[u][][k],min(dp[u][][b]+dp[v][][a]+dist[v],dp[u][][b]+dp[v][][a])+dist[v]);
dp[u][][k] = min(dp[u][][k],dp[u][][b]+dp[v][][a]+dist[v]*);
}
}
}
if(!--deg[fa[u]]) q.PS(fa[u]);//fa[root]虽然不确定,但是在0~500内且deg = 0
}
return u;
} //#define LOCAL
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif
while(scanf("%d",&n),n){
memset(deg,,sizeof(deg));
memset(hd,-,sizeof(hd)); ec = ;
for(int i = ; i < n; i++){
int u,f,d; scanf("%d%d%d",&u,&f,&d);
fa[u] = f; dist[u] = d;
add(f,u); deg[f]++;
}
printf("Case %d:\n",++ks);
int *ans = dp[sol()][];
int Q; scanf("%d",&Q);
while(Q--){
int x; scanf("%d",&x);
printf("%d\n",upper_bound(ans,ans+n,x)-ans);//能走的最大子结点数+1
}
}
return ;
}
UVA Live Archive 4015 Cave (树形dp,分组背包)的更多相关文章
- HDU4003Find Metal Mineral[树形DP 分组背包]
Find Metal Mineral Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Other ...
- HDU-1011 Starship Troopers (树形DP+分组背包)
题目大意:给一棵有根带点权树,并且给出容量.求在不超过容量下的最大权值.前提是选完父节点才能选子节点. 题目分析:树上的分组背包. ps:特判m为0时的情况. 代码如下: # include<i ...
- Ural-1018 Binary Apple Tree(树形dp+分组背包)
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #i ...
- 【P2015】二叉苹果树 (树形DP分组背包)
题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 现在这颗树枝条太多了,需要剪枝.但是 ...
- hdu 1561 树形dp+分组背包
题意:就是给定n个点,每个地点有value[i]的宝物,而且有的宝物必须是另一个宝物取了才能取,问取m个点可以获得的最多宝物价值. 一个子节点就可以返回m个状态,每个状态表示容量为j(j<=m) ...
- poj2486 Apple Tree (树形dp+分组背包)
题目链接:https://vjudge.net/problem/POJ-2486 题意:一棵点权树,起点在1,求最多经过m条边的最大点权和. 思路: 树形dp经典题.用3维状态,dp[u][j][0/ ...
- hdu1561 The more, The Better 树形DP+分组背包
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1561 思路: 典型的树形背包题目: 定义dp[i][j]表示以i为根节点,攻打j个城堡的获得的财宝的最 ...
- hdu 4003 树形dp+分组背包 2011大连赛区网络赛C
题意:求K个机器人从同一点出发,遍历所有点所需的最小花费 链接:点我 Sample Input 3 1 1 //3个点,从1出发,1个机器人 1 2 1 1 3 1 3 1 2 1 2 1 1 3 1 ...
- HDU-4003 Find Metal Mineral (树形DP+分组背包)
题目大意:用m个机器人去遍历有n个节点的有根树,边权代表一个机器人通过这条边的代价,求最小代价. 题目分析:定义状态dp(root,k)表示最终遍历完成后以root为根节点的子树中有k个机器人时产生的 ...
随机推荐
- 解决Navicat 连接服务器数据库报10060问题
1.登录mysql,授予远程登录权限(确保mysql表里的登录user对应的host为 % 即可:若不是 % ,使用mysql的update更新对应host) mysql> use mysql; ...
- 浅谈JavaScript--this指向
js中this的值取决于调用的模式 方法调用模式 var student={ name:"adoctors", showThis:function(){ console.log(t ...
- Codeforces Round #558 (Div. 2)B(SET,模拟)
#include<bits/stdc++.h>using namespace std;int a[100007];int cnt[100007];int main(){ int n; ...
- 51nod1010(枚举+二分)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1010 题意:中文题诶- 思路:求第一个比 x (1<= ...
- MVVM与Controller瘦身实践
MVC是一个做iOS开发都知道的设计模式,也是Apple官方推荐的设计模式.实际上,Cocoa Touch就是按照MVC来设计的. 这里,我们先不讲MVC是什么,我们先来谈谈软件设计的一些原则或者说理 ...
- 视图、存储函数、存储过程、触发器:MySQL系列之五
一.视图 视图:VIEW,虚表,保存有实表的查询结果,实际数据不保存在磁盘 物化视图:实际数据在磁盘中有保存,加快访问,MySQL不支持物化视图 基表:视图依赖的表 视图中的数据事实上存储于" ...
- 理解js继承的6种方式
想要继承,就必须要提供个父类(继承谁,提供继承的属性) 一.原型链继承 重点:让新实例的原型等于父类的实例. 特点:1.实例可继承的属性有:实例的构造函数的属性,父类构造函数属性,父类原型的属性.(新 ...
- BestCoder Round #86 1002
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5805 题意:删除数列中一个数,找出相邻之差绝对值最大,求依次删除最大值的和 解法:删除边缘位置的数字需要注 ...
- Linux中vim编辑器的缩进的功能键
vim编程时,经常需要对代码进行缩进处理,以增加程序的可读性和后期的代码维护. 可以采用多种方式达到缩进的目的: 1) 命令模式(command mode) 2) Visual模式(visual mo ...
- Dedecms标签arclistsg调用单表模型出错的解决方法
使用arclistsg标签调用分类信息等单表模型出错提示Column 'id' in where clause is ambiguous, 修改文件:include\taglib\arclistsg ...