和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,分组背包)的更多相关文章

  1. HDU4003Find Metal Mineral[树形DP 分组背包]

    Find Metal Mineral Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Other ...

  2. HDU-1011 Starship Troopers (树形DP+分组背包)

    题目大意:给一棵有根带点权树,并且给出容量.求在不超过容量下的最大权值.前提是选完父节点才能选子节点. 题目分析:树上的分组背包. ps:特判m为0时的情况. 代码如下: # include<i ...

  3. Ural-1018 Binary Apple Tree(树形dp+分组背包)

    #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #i ...

  4. 【P2015】二叉苹果树 (树形DP分组背包)

    题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 现在这颗树枝条太多了,需要剪枝.但是 ...

  5. hdu 1561 树形dp+分组背包

    题意:就是给定n个点,每个地点有value[i]的宝物,而且有的宝物必须是另一个宝物取了才能取,问取m个点可以获得的最多宝物价值. 一个子节点就可以返回m个状态,每个状态表示容量为j(j<=m) ...

  6. poj2486 Apple Tree (树形dp+分组背包)

    题目链接:https://vjudge.net/problem/POJ-2486 题意:一棵点权树,起点在1,求最多经过m条边的最大点权和. 思路: 树形dp经典题.用3维状态,dp[u][j][0/ ...

  7. hdu1561 The more, The Better 树形DP+分组背包

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1561 思路: 典型的树形背包题目: 定义dp[i][j]表示以i为根节点,攻打j个城堡的获得的财宝的最 ...

  8. 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 ...

  9. HDU-4003 Find Metal Mineral (树形DP+分组背包)

    题目大意:用m个机器人去遍历有n个节点的有根树,边权代表一个机器人通过这条边的代价,求最小代价. 题目分析:定义状态dp(root,k)表示最终遍历完成后以root为根节点的子树中有k个机器人时产生的 ...

随机推荐

  1. VS连接SQL Server数据库,增删改查详细教程(C#代码)_转载

    工具: 1.Visual Studio (我使用的是vs2013) 2.SQL Server  (我使用的是sql server2008) 操作: 1.打开SQL Server,打开后会看到数据库的初 ...

  2. elasticsearch 基本介绍

    1. Elasticsearch的适用场景: (1)类似百度百科的全文检索,高亮,搜索推荐(2)新闻类的搜索,用户行为日志(点击,浏览,收藏,评论)+社交网络数据(对某某新闻的相关看法),数据分析,给 ...

  3. eclipse中项目已经启动,可是tomcat一直显示在启动中

    一.异常描述 1. 在eclipse中启动tomcat,应用已经启动成功,但是tomcat仍然一直处于starting装填 二.分析原因 1. 更换8080端口为9080,启动tomcat,可以完整启 ...

  4. 51nod1138(连续和)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1138 题意:中文题诶- 思路:假设 x=a1+(a1+1)+ ...

  5. CF 984C Finite or not? (数论)

    CF 984C Finite or not? (数论) 给定T(T<=1e5)组数据,每组数据给出十进制表示下的整数p,q,b,求问p/q在b进制意义下是否是有限小数. 首先我们先把p/q约分一 ...

  6. ThinkSNS+ PHP开发概述

    Plus (读音:[plʌs],全称:ThinkSNS+ [θɪŋk es en es plʌs],是 ThinkSNS 系列产品一个重要版本,其软件识别名称为 Plus 即 +) 是一个基于 Lat ...

  7. QuotaExceededError: The quota has been exceeded. localStorage缓存超出限制

    今天在项目中遇到了一个问题,localStorage存储超出限制.报错信息如标题.这个是因为最近做了一波优化,把导航栏和一些用户信息本地化存储,都放在localStorage里,也不是每个用户会出现这 ...

  8. 关于状态压缩DP以及状态压缩

    首先要明确:状态压缩是利用数字来代表一组序列的方法,从而降低序列访问的复杂度,本质上跟HASH有着差不多的思想,但是其实就是数位运算的一种 定义:集合中共有N个数字,其中每个数字均小于K,能么我们可以 ...

  9. shiro 重定向 后 带有 sessionId 的 解决 办法

    http://blog.csdn.net/aofavx/article/details/51701012

  10. BZOJ 1053 [HAOI2007]反素数ant 神奇的约数

    本蒟蒻终于开始接触数学了...之前写的都忘了...忽然想起来某神犇在几个月前就切了FWT了... 给出三个结论: 1.1-N中的反素数是1-N中约数最多但是最小的数 2.1-N中的所有数的质因子种类不 ...