題目描述
有一棵蘋果樹,如果樹枝有分叉,一定是分2叉(就是說沒有只有1個兒子的結點)
這棵樹共有n個結點(葉子點或者樹枝分叉點),編號為1-n,樹根編號一定是1。
我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹
2 5\ /
3 4\ /
1現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋果。
給定需要保留的樹枝數量,求出最多能留住多少蘋果。
輸入格式
第1行2個數,n和q(1<=q<= n,1n表示樹的結點數,q表示要保留的樹枝數量。接下來n-1行描述樹枝的資訊。
每行3個整數,前兩個是它連線的結點的編號。第3個數是這根樹枝上蘋果的數量。
每根樹枝上的蘋果不超過30000個。
輸出格式
乙個數,最多能留住的蘋果的數量。
輸入輸出樣例
輸入5 2
1 3 1
1 4 10
2 3 20
3 5 20
輸出21
這道題使用樹形dp的思路。先把樹作為無向圖儲存,**如下:
int head[
105]
,tot=0;
struct eedge[
205]
;void
add(
int a,
int b,
int c)
head儲存是連線每個節點的第一條邊在edge中的下標,通過尋找每條邊的next就可以找到連線該點的每一條邊。
然後再搜尋所有節點並找出每個節點保留一定數量的邊時最多能保留幾個蘋果,**如下:
int sm[
105]
;int n,q,f[
105]
[105];
void
dfs(
int a,
int fa)}}
}
sm是這個結點下的結點總數,f是動態規劃陣列。
先找搜尋子樹然後回溯再進行動態規劃,a是當前搜尋的結點,fa是該結點的父節點,j表示保留a的幾個樹枝,k表示保留子樹i的幾個樹枝多-1是因為還有連線i的一根樹枝所以也要加上i上的蘋果。
下面是ac**
#include
using
namespace std;
int head[
105]
,tot=0;
struct eedge[
205]
;void
add(
int a,
int b,
int c)
int sm[
105]
;int n,q,f[
105]
[105];
void
dfs(
int a,
int fa)}}
}int
main()
dfs(1,
-1);
cout<[q]
}
P2015 二叉蘋果樹(樹形dp)
題目傳送門 description 有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 34 1現在這顆樹枝條太多...
洛谷P2015 蘋果二叉樹(樹形dp)
給出乙個n個點的二叉樹,樹上有邊權,求留下q個樹枝能夠獲得的最大收益為多少。dp i j d p i j 表示在以 i i 為根的節點,留下 j role presentation j j個分支,的最大收益值。設u u 為當前遍歷到的根節點,v role presentation v v為訪問的子節...
洛谷 P2015 二叉蘋果樹 樹形dp
有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 3 4 1現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋...