題目描述
有一棵蘋果樹,如果樹枝有分叉,一定是分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現在這顆樹枝條太多了,需要剪枝。但是一些樹枝...