洛谷 P2015 二叉蘋果樹 樹形dp

2021-09-26 09:54:05 字數 1252 閱讀 6850

有一棵蘋果樹,如果樹枝有分叉,一定是分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個。

乙個數,最多能留住的蘋果的數量。

輸入 #1複製

5 2

1 3 1

1 4 10

2 3 20

3 5 20

輸出 #1複製

21
和選課那題很像啊。

從根節點往下找m條邊使得最後得到的蘋果數最多,最後得到的還得是個完整的樹。

在看本題之前,建議先去看一下p2014 選課。

令dp[i][j]為節點i的子樹上保留j條邊,能保留的最多蘋果數。顯然,在節點i的子樹上保留邊和節點i沒有關係。在選課那一題中,節點i在它的子樹上選擇j門課是包含自身的,因為i是先修課。

所以方程會和選課略有不同:

dp[i][j]=max(dp[i][j],dp[i][j-k-1]+dp[son][k])

答案為dp[1][m]。

#include #include using namespace std;

int n,m,s,head[1001],cnt,dp[1001][1001],value[1001][1001];

bool vis[1001];//用vis陣列記錄判斷父節點跳過的問題也是一樣的

struct node

e[2001];

inline void add(int u,int v,int val)

void dfs(int i,int fa)

} }}signed main()

dfs(1,-1);

cout

}

洛谷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現在這顆樹枝條太多了,需要剪枝。但是一些樹枝...

洛谷P2015 二叉蘋果樹 樹形DP

有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 34 1現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋果...