洛谷P2015 二叉蘋果樹(樹形dp)

2022-05-25 03:27:11 字數 1356 閱讀 9449

題目描述

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

1 4 10

2 3 20

3 5 20

輸出樣例#1:

狀態:dp[u][x]表示以節點u為根的子樹保留x條邊時,可以得到的最大值。

轉移方程:dp[u][x]=max(dp[u][x],dp[u][x-k-1]+dp[v][k]+s[i].w)

(其中v是節點u的任意兒子節點,1<=x<=min(sum[u],q),0<=k<=min(x-1,q)。)

(x-1是因為節點u和節點v之間的邊必須選。sum[a]表示以節點a為根的子樹的邊數。)

實現:樹根已經確定為1,便從1開始dfs一步步從後向前推即可。

ps:仍然感謝某「狗」星人。

#include #include #include #include #include #include #include #include #define ll long long

#define pi acos(-1.0)

const int maxn=210;

const int inf=0x3f3f3f3f;

using namespace std;

struct side

s[maxn];

int head[maxn],cnt,dp[maxn][maxn],q,sum[maxn];

void add(int u,int v,int w)

void dfs(int u,int fa)

}return ;

}int main(void)

dfs(1,0);

printf("%d\n",dp[1][q]);

return 0;

}

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