题目大意:

从一个根节点出发,走最多 x 的长度,问最多能走过多少个节点,图保证是一棵树

dp[0][i][j] , 表示走从i点为根的子树走过了j个点最后回到 i 最少需要多少时间
dp[1][i][j] , 同理,但表示不需要回到 i
那么由儿子不断向父亲更新,有4种情况

1.if(dp[0][u][k+j]<0 || dp[0][u][k+j]>dp[0][v][j]+dp[0][u][k]+2*e[i].d)
                    dp[0][u][k+j]=dp[0][v][j]+dp[0][u][k]+2*e[i].d;

2.if(dp[1][u][k+j]<0 || dp[1][u][k+j]>dp[0][v][j]+dp[0][u][k]+e[i].d)
                    dp[1][u][k+j]=dp[0][v][j]+dp[0][u][k]+e[i].d;

3.if(dp[1][u][k+j]<0 || dp[1][u][k+j]>dp[1][v][j]+dp[0][u][k]+e[i].d)
                    dp[1][u][k+j]=dp[1][v][j]+dp[0][u][k]+e[i].d;

4.if(dp[1][u][k+j]<0 || dp[1][u][k+j]>dp[0][v][j]+dp[1][u][k]+2*e[i].d)
                    dp[1][u][k+j]=dp[0][v][j]+dp[1][u][k]+2*e[i].d;

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath> using namespace std;
#define N 505
#define ll long long
ll dp[][N][N];
int fa[N] , n , m;
int first[N],k; struct Edge{
int y , next , d;
Edge(int y= , int next= , int d=):y(y),next(next),d(d){}
}e[N<<]; void add_edge(int x , int y , int d)
{
e[k] = Edge(y , first[x] , d);
first[x] = k++;
} void dfs(int u)
{
dp[][u][] = ;
for(int i=first[u] ; ~i ; i=e[i].next){
int v = e[i].y;
dfs(v);
for(int k=n ; k>= ; k--)
{
if(dp[][u][k]<) continue;
for(int j= ; j<n ; j++){
if(dp[][v][j]<) continue;
if(dp[][u][k+j]< || dp[][u][k+j]>dp[][v][j]+dp[][u][k]+*e[i].d)
dp[][u][k+j]=dp[][v][j]+dp[][u][k]+*e[i].d;
if(dp[][u][k+j]< || dp[][u][k+j]>dp[][v][j]+dp[][u][k]+e[i].d)
dp[][u][k+j]=dp[][v][j]+dp[][u][k]+e[i].d; if(dp[][v][j]<) continue;
if(dp[][u][k+j]< || dp[][u][k+j]>dp[][v][j]+dp[][u][k]+e[i].d)
dp[][u][k+j]=dp[][v][j]+dp[][u][k]+e[i].d;
}
if(dp[][u][k]<) continue;
for(int j= ; j<=n ; j++){
if(dp[][v][j]<) continue;
if(dp[][u][k+j]< || dp[][u][k+j]>dp[][v][j]+dp[][u][k]+*e[i].d)
dp[][u][k+j]=dp[][v][j]+dp[][u][k]+*e[i].d;
}
}
}
} int main()
{
#ifndef ONLINE_JUDGE
freopen("a.in" , "r" , stdin);
#endif // ONLINE_JUDGE
int cas = ;
while(scanf("%d" , &n) , n)
{
printf("Case %d:\n" , ++cas);
memset(first , - , sizeof(first));
k = ;
for(int i= ; i<=n ; i++) fa[i]=i;
for(int i= ; i<n ; i++){
int u,v,d;
scanf("%d%d%d" , &u , &v , &d);
u++ , v++;
add_edge(v , u , d);
fa[u] = v;
}
int st;
for(int i= ; i<=n ; i++)
if(fa[i]==i) st = i; memset(dp , - , sizeof(dp));
dfs(st);
/*debug
for(int i=1 ; i<=n ; i++){
for(int j=1 ; j<=n ; j++){
printf("%4I64d" , dp[1][i][j]);
}
cout<<endl;
}*/
scanf("%d" , &m);
for(int i= ; i<m ; i++){
int x;
scanf("%d" , &x);
int ret = ;
for(int t= ; t<=n ; t++){
// cout<<dp[0][1][t]<<" "<<dp[1][1][t]<<endl;
if((dp[][st][t]<=x && dp[][st][t]>=) || (dp[][st][t]<=x && dp[][st][t]>=))
ret = max(ret , t);
}
printf("%d\n" , ret);
}
}
return ;
}

UVALive 4015 树形dp的更多相关文章

  1. 算法笔记--树的直径 && 树形dp && 虚树 && 树分治 && 树上差分 && 树链剖分

    树的直径: 利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点. 先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c ...

  2. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

  3. COGS 2532. [HZOI 2016]树之美 树形dp

    可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...

  4. 【BZOJ-4726】Sabota? 树形DP

    4726: [POI2017]Sabota? Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 128  Solved ...

  5. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  6. 树形DP

    切题ing!!!!! HDU  2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...

  7. BZOJ 2286 消耗战 (虚树+树形DP)

    给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...

  8. POJ2342 树形dp

    原题:http://poj.org/problem?id=2342 树形dp入门题. 我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式 ...

  9. hdu1561 The more, The Better (树形dp+背包)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1561 思路:树形dp+01背包 //看注释可以懂 用vector建树更简单. 代码: #i ...

随机推荐

  1. Linux在线安装pip和numpy

    最近写Python需要用到numpy包 运行pip install numpy就会自动安装 一.因此需要先安装pip 1.如果安装的是Python>=2.7.9或者Python>=3.4, ...

  2. PowerShell~文件操作和对象遍历

    ps提供了丰富的文件操作,如建立,删除,改名,移动,复制,文件夹建立,显示文件列表,同时对数组对象的遍历也很方便,如果在使用PS脚本时,希望现时传入参数,可以把参数声明为param,当然需要把它写在文 ...

  3. zoj3768Continuous Login

    链接 这题通过暴力可以看出最多不超过3 具体为什么..等着看大牛的题解. 可以预处理出来两个数之和 用bool存下 然后枚举一个数 二分剩余数的位置就可以了 勉强可过 #include <ios ...

  4. android开发学习 ------- 【转】EventBus的学习理解

    EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间.组件与后台线程间的通信. 比如请求网络,等网络返回时通过Handler或Broadca ...

  5. AJPFX总结Collection集合(下)

    List集合特有方法 特有方法.凡是可以操作角标的方法都是该体系特有的方法. 增          add(index,element);在指定位置添加元素          addAll(index ...

  6. http接口调用,传递json格式带双引号问题

    springmvc 配置好会自动转换json格式,只要配置他转格式之前,在转次String类型就好

  7. PHP memcache扩展安装 for Windows

    一.下载并安装memcached服务器端软件    1.下载memcached软件 32位下载地址: memcached-win32-1.4.4-14.zip(直接下载),memcached-win3 ...

  8. WPF知识点全攻略01- WPF相对WinFrom的优缺点

    对比WPF和WinFrom前,先来了解下GUI现阶段在用的其他一些开发技术: MFC:微软基础类库,以C++的形式封装了Windows API,加上一些实用工具类. QT:奇趣科技开发的跨平台C++图 ...

  9. upload 上传 加token 在 :headers='headers' 注意 不要直接写$refs.upload.headers = {} 这样vue会警告 修改组件内部变量

    upload 上传 加token 在 :headers='headers' 注意 不要直接写$refs.upload.headers = {} 这样vue会警告 修改组件内部变量 <Upload ...

  10. Element UI tree 回显问题

    Part.1 问题 写项目时遇到一个棘手的问题,在做关于权限功能时,点击修改需要显示角色原本对应的权限.涉及到了 tree 组件回显,但是有一个很尴尬的问题:tree 组件只要父节点选中,那么子节点就 ...