LA 4015 树形背包

题目链接:https://vjudge.net/contest/164840#problem/D

题意: 给一棵树,每条边上有一些权值,求 长度不超过 x ,最多能走多少个点;

 

分析:

考虑每一个节点,他可以一直走下去,也可以走回来而走到他的兄弟节点;

 

状态定义: 

d[x][j][0/1] 从 i 出发,走 j 个节点的最短距离;

1、回来,这就是一个背包,更新当前节点;

2、不回来,则是要考虑从哪个部分不回来;

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 int n;
 6 const int maxn = 550;
 7 const int inf = 0x3f3f3f3f;
 8 vector <int> g[maxn];
 9 int cnt[maxn];
10 int son[maxn];
11 
12 int d[maxn][maxn][2];
13 
14 void dfs(int x) {
15 
16     for(int i=1; i<=n; i++)
17         d[x][i][0] = d[x][i][1] = inf;
18     d[x][1][0] = d[x][1][1] = 0;
19 
20 
21     son[x] = 1;
22     for(int i=0; i<g[x].size(); i+=2) {
23         int y = g[x][i];
24         int len = g[x][i+1];
25         dfs(y);
26 
27         for(int j=son[x]; j>0; j--) {   ///这一重 相当于前面几个背包
28             for(int k=1; k<=son[y]; k++) {  ///这一重 相当于当前这个背包中拿物品
29                 d[x][j+k][1] = min(d[x][j+k][1],d[x][j][1]+d[y][k][1]+len*2);
30                 d[x][j+k][0] = min(d[x][j+k][0],min(d[x][j][0]+d[y][k][1]+len*2,d[x][j][1]+d[y][k][0]+len));
31             }
32         }
33 
34         son[x] +=son[y];
35     }
36 }
37 
38 int main() {
39     int cas = 1;
40     while(scanf("%d",&n),n) {
41         for(int i=0; i<=n; i++)
42             g[i].clear();
43 
44         memset(cnt,0,sizeof(cnt));
45         for(int i=0; i<n-1; i++) {
46             int u,v,w;
47             scanf("%d%d%d",&u,&v,&w);
48             cnt[u]++;
49             g[v].push_back(u);
50             g[v].push_back(w);
51         }
52 
53         int root = 0;
54         for(int i=1; i<n; i++)
55             if(!cnt[i])
56                 root = i;
57 
58         dfs(root);
59         int q,x;
60         scanf("%d",&q);
61         printf("Case %d:\n",cas++);
62         while (q--) {
63             scanf("%d",&x);
64             int ans = 1;
65             for (int i = 1; i <= n; i++)
66                 if (d[root][i][0] <= x)
67                     ans = i;
68             printf("%d\n",ans);
69         }
70 
71     }
72     return 0;
73 }
View Code

 

膜拜猫奴大牛;

转载于:https://www.cnblogs.com/TreeDream/p/6900851.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值