题目大意:

从一个根节点出发,走最多 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 ;
}

最新文章

  1. JDK安装与环境变量配置
  2. MySQL事件 Events
  3. Asp.Net Web API 2第九课——自承载Web API
  4. Apply Root Motion
  5. 关于背景透明,文字不透明的最佳方法,兼容IE
  6. CoffeeScript 入门笔记
  7. 查看Oracle有哪些表或者视图
  8. 关于 javascript event flow 的一个bug
  9. Spring+MVC+Mybatis整合
  10. JDBCTemplate简化JDBC的操作(三)需要注意的地方
  11. ●BZOJ 4310 跳蚤
  12. 从驱动层分析android的Binder机制-android学习之旅(83)
  13. The SDK &#39;Microsoft.NET.Sdk&#39; specified could not be found.
  14. scrapy选择器归纳
  15. PHP判断手机、电脑访问
  16. 【题解】 bzoj2006: [NOI2010]超级钢琴 (ST表+贪心)
  17. taro 在components文件夹中 新建组件时,组件支持自定义命名,但是不能大写开头
  18. byr面经两则
  19. [USACO08JAN]Telephone Lines
  20. Cgroups子系统介绍

热门文章

  1. Spring------自动化装配Bean(三)
  2. 01认识Python和基础知识
  3. 初学web前端,掌握这些就足够了!
  4. cordova应用使用手机调试
  5. http://bbs.chinaunix.net/thread-1463276-1-1.html
  6. 正确使用MySQL JDBC setFetchSize()方法解决JDBC处理大结果
  7. 屏幕卫士模式系统APP开发
  8. 二叉排序树BST
  9. 二分 || UOJ 148 跳石头
  10. 【讲●解】KMP算法