洛谷P2015 二叉苹果树【树形dp】
P2015 二叉蘋果樹
時間限制 1.00s
內存限制 125.00MB
題目描述
有一棵蘋果樹,如果樹枝有分叉,一定是分2叉(就是說沒有只有1個兒子的結點)
這棵樹共有N個結點(葉子點或者樹枝分叉點),編號為1-N,樹根編號一定是1。
我們用一根樹枝兩端連接的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹
2 5
\ /
3 4
\ /
1
現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋果。
給定需要保留的樹枝數量,求出最多能留住多少蘋果。
輸入格式
第1行2個數,N和Q(1<=Q<= N,1<N<=100)。
N表示樹的結點數,Q表示要保留的樹枝數量。接下來N-1行描述樹枝的信息。
每行3個整數,前兩個是它連接的結點的編號。第3個數是這根樹枝上蘋果的數量。
每根樹枝上的蘋果不超過30000個。
輸出格式
一個數,最多能留住的蘋果的數量。
輸入輸出樣例
輸入 #1 復制
5 2
1 3 1
1 4 10
2 3 20
3 5 20
輸出 #1 復制
21
解題思路:
dp[u][j]dp[u][j]dp[u][j]:以第uuu節點為根的子樹保留jjj所留下的最大蘋果數
則:dp[u][j]=max(dp[u][j],dp[u][j?k]+dp[v][k?1]+val)dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k-1]+val)dp[u][j]=max(dp[u][j],dp[u][j?k]+dp[v][k?1]+val)
因此要先一個循環遍歷jjj的值,jjj最多的值為樹的邊數與需保留的邊數的較小值
還需遍歷kkk的值,即其子樹能保留的邊數
代碼:
#include <cstdio> #include <iostream> #include <algorithm> #include <cmath> #include <cstdlib> #include <cstring> #include <map> #include <stack> #include <queue> #include <vector> #include <bitset> #include <set> #include <utility> #include <sstream> #include <iomanip> using namespace std; typedef long long ll; typedef unsigned long long ull; #define inf 0x3f3f3f3f #define rep(i,l,r) for(int i=l;i<=r;i++) #define lep(i,l,r) for(int i=l;i>=r;i--) #define ms(arr) memset(arr,0,sizeof(arr)) //priority_queue<int,vector<int> ,greater<int> >q; const int maxn = (int)1e5 + 5; const ll mod = 1e9+7; struct node {int to;int val;node(int _to,int _val) {to=_to;val=_val;} }; vector<node> m[120]; int n,k; int dp[120][120]; int dfs(int s,int f) {int d=0;for(int i=0;i<m[s].size();i++) {if(m[s][i].to==f) continue;d+=dfs(m[s][i].to,s)+1;for(int j=min(k,d);j>0;j--) {for(int t=min(j,d);t>0;t--) {dp[s][j]=max(dp[s][j],dp[m[s][i].to][t-1]+dp[s][j-t]+m[s][i].val);}}}return d; } int main() {#ifndef ONLINE_JUDGEfreopen("in.txt", "r", stdin);#endif//freopen("out.txt", "w", stdout);//ios::sync_with_stdio(0),cin.tie(0);scanf("%d %d",&n,&k);int a,b,c;rep(i,1,n-1) {scanf("%d %d %d",&a,&b,&c);m[a].push_back(node(b,c));m[b].push_back(node(a,c));}dfs(1,0);printf("%d\n",dp[1][k]);return 0; }總結
以上是生活随笔為你收集整理的洛谷P2015 二叉苹果树【树形dp】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Problem A: 判断操作是否合法(
- 下一篇: 堆树