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个机器人时产生的 ...
随机推荐
- Codeforces Round #523 (Div. 2)C(DP,数学)
#include<bits/stdc++.h>using namespace std;long long a[100007];long long dp[1000007];const int ...
- 洛谷P1912 [NOI2009]诗人小G(决策单调性)
传送门 题解 决策单调性是个啥……导函数是个啥……这题解讲的是啥……我是个啥…… //minamoto #include<iostream> #include<cstdio> ...
- asddf
https://docs.saltstack.com/en/getstarted/fundamentals/index.html https://pypi.org/simple/cherrypy/ 安 ...
- linux日志守护进程 syslog
几乎所有的网络设备都可以通过syslog协议,将日志信息以UDP的形式传送给远端服务器,远端接收日志服务器必须通过syslogd监听UDP端口514,并根据 syslog.conf 配置文件张的配置处 ...
- STP-19-Port-Channel发现和配置
工程师在给一台交换机上的特定Port-Channel增加多个端口时,有一些配置参数必须相同,如下所示: 使用相同的速率和双工设置: 使用相同的操作模式(Trunk.Access.动态): 若不为T ...
- 主键约束 primary key
主键的作用: 可以唯一标识 一条数据,每张表里面只能有一个主键,.主键特性: 非空且唯一.当表里没有主键的时,第一个出现的非空且为唯一的列,被当成主键. 例子:create table tb3( ...
- POJ2758 Checking the Text 哈希
注意到插入次数挺少的,于是每次暴力重构,然后哈希+二分 #include<cstdio> #include<iostream> #include<algorithm> ...
- python import error:no module named yaml
解决办法: python2 : sudo apt-get install python-yaml python3 : sudo apt-get install python3-yaml
- InteliJ idea import project 找不到文件结构解决办法
一.按下列步骤操作: 1. 关闭IDEA, 2.然后删除项目文件夹下的.idea文件夹 3.重新用IDEA工具打开项目: 二.import新项目之后,可能需要等1 ...
- 一起来学Spring Cloud | 第一章 :如何搭建一个多模块的springcloud项目
在spring cloud系列章节中,本来已经写了几个章节了,但是自己看起来有些东西写得比较杂,所以重构了一下springcloud的章节内容,新写了本章节,先教大家在工作中如何搭建一个多模块的spr ...