題目描述
有一棵蘋果樹,如果樹枝有分叉,一定是分2
22叉(就是說沒有只有1
11個兒子的結點)
這棵樹共有n
nn個結點(葉子點或者樹枝分叉點),編號為1−n
1-n1−
n,樹根編號一定是111。
我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4
44個樹枝的樹。
現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋果。
給定需要保留的樹枝數量,求出最多能留住多少蘋果。
輸入格式
第1
11行2
22個數,n
nn和q(1
<=q
<=n
,1
<
n<
=100
)q(1<=q<= n,1q(
1<=q
<=n
,1<
n<=1
00)。
n
nn表示樹的結點數,q
qq表示要保留的樹枝數量。接下來n−1
n-1n−
1行描述樹枝的資訊。
每行3
33個整數,前兩個是它連線的結點的編號。第3
33個數是這根樹枝上蘋果的數量。
每根樹枝上的蘋果不超過30000
30000
30000個。
輸出格式
乙個數,最多能留住的蘋果的數量。
輸入輸出樣例
輸入5 2
1 3 1
1 4 10
2 3 20
3 5 20
輸出21
解題思路
這是一道樹形dpdp
dp的板子題。
f [i
][j]
f[i][j]
f[i][j
]表示以i
ii為根節點的子樹,保留j
jj條樹枝時的,保留的最大蘋果數。
(這道題有乙個隱含的條件,當某條邊被保留下來時,從根節點到這條邊的路徑上的所有邊也都必須保留下來)那麼狀態轉移方程為:
dep表示當前節點,son是dep的乙個子節點,
為什麼是f[d
ep][
i−k−
1]
f[dep][i-k-1]
f[dep]
[i−k
−1]而不是f[d
ep][
i−k]
f[dep][i-k]
f[dep]
[i−k
]?因為保留一條邊必須保留從根節點到這條邊路徑上的所有邊,那麼如果你想從uu的子節點vv的子樹上留邊的話,也要留下u,v
u,vu,
v之間的連邊。
**
#include
#include
#include
#include
using namespace std;
int n,q,x,y,z,a[
110]
[110
],s[
110]
[110
],f[
110]
[110
],c[
110]
,v[110];
void
dfs(int dep)}}
} int main()
dfs(1)
;printf
("%d"
,f[1
][q]);
return0;
}
洛谷 P2015 二叉蘋果樹 樹形dp
有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 3 4 1現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋...
洛谷P2015 二叉蘋果樹(樹形dp)
有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 3 4 1現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋...
洛谷P2015 二叉蘋果樹 樹形dp)
題目描述 有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 34 1現在這顆樹枝條太多了,需要剪枝。但是一些樹枝...