二叉苹果树

乍一看好像挺简单的想都没想就开始建图...

直接忽略这是棵树...

然后做着做着就卡了

最后还是看了题解

不过真的挺简单的...人蠢嘛没办法

注意的地方大概就是dp特判和tree初始化不能为0吧

题目描述

有一棵二叉苹果树,如果数字有分叉,一定是分两叉,即没有只有一个儿子的节点。这棵树共 N 个节点,标号 1 至 N,树根编号一定为 1。

我们用一根树枝两端连接的节点编号描述一根树枝的位置。一棵有四根树枝的苹果树,因为树枝太多了,需要剪枝。但是一些树枝上长有苹果,给定需要保留的树枝数量,求最多能留住多少苹果。

输入格式

第一行两个数 NQN表示树的节点数,Q 表示要保留的树枝数量。

接下来 N−1 行描述树枝信息,每行三个整数,前两个是它连接的节点的编号,第三个数是这根树枝上苹果数量。

输出格式

输出仅一行,表示最多能留住的苹果的数量。

样例

样例输入

5 2
1 3 1
1 4 10
2 3 20
3 5 20

样例输出

21

数据范围与提示

对于 100%的数据,1≤Q≤N≤100,N≠1 , 每根树枝上苹果不超过 30000 个。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int MAXN = 1e7 + 5 ;
 5 
 6 int n , m , a , b , c ;
 7 int left_son[105] , right_son[105] , apple[105] ;
 8 int tree[105][105] , f[105][105] ;
 9 
10 int read(){
11     char c ;
12     int sign = 1 ;
13     while((c = getchar()) < '0' || c > '9') 
14         if(c == '-') sign = -1 ;
15     int Ans = c - '0' ;
16     while((c = getchar()) >= '0' && c <= '9')
17         Ans = Ans * 10 + c - '0' ;
18     return Ans * sign ;
19 }
20 
21 void plant_tree(int a){
22     for(int i = 1 ; i <= n ; ++ i)
23         if(tree[a][i] >= 0){
24             left_son[a] = i ;
25             apple[i] = tree[a][i] ;
26             tree[a][i] = tree[i][a] = -1 ;
27             plant_tree(i) ;
28             break ;
29         }
30     for(int i = 1 ; i <= n ; ++ i)
31         if(tree[a][i] >= 0){
32             right_son[a] = i ;
33             apple[i] = tree[a][i] ;
34             tree[a][i] = tree[i][a] = -1 ;
35             plant_tree(i) ;
36             break ;
37         }
38 }
39 
40 int DP(int a , int k){
41     if(k == 0) return 0 ;
42     if(left_son[a] == 0 && right_son[a] == 0) return apple[a] ;//理解f[a][k]是一定要取a这个点的
43     if(f[a][k]) return f[a][k] ;
44     for(int i = 0 ; i <= k - 1 ; ++ i){//最多只能到k-1
45         f[a][k] = max(f[a][k] , DP(left_son[a] , i) + DP(right_son[a] , k - i - 1) + apple[a]) ;
46     }
47     return f[a][k] ;
48 }
49 
50 int main(){
51     n = read() , m = read() ;
52     ++ m ;
53     for(int i = 1 ; i <= n ; ++ i){
54         for(int j = 1 ; j <= n ; ++ j){
55             tree[i][j] = -1 ;
56         }
57     }
58     for(int i = 1 ; i <= n - 1 ; ++ i){
59         a = read() , b = read() , c = read() ;
60         tree[a][b] = tree[b][a] = c ;//双向边
61     }
62     plant_tree(1) ;
63     cout << DP(1 , m) ;
64     return 0 ;
65 }

猜你喜欢

转载自www.cnblogs.com/GC-hahaha/p/9494431.html
今日推荐