1. 程式人生 > >URAL-1018 Binary Apple Tree---樹形DP

URAL-1018 Binary Apple Tree---樹形DP

main sin nbsp eof 有一個 root for i++ 樹形dp

題目鏈接:

https://cn.vjudge.net/problem/URAL-1018

題目大意:

給你一棵樹,每條邊有一個邊權,求以1為根節點,q條邊的子數(q+1個點),邊權和至最大。

解題思路:

dp[root][j], 表示以root為根節點,保留j個節點的最大邊權和。

dp[root][j]=max(dp[root][j],dp[root][j-t]+dp[son][t]+len);

t的範圍從1到j - 1,因為每個點從dp[][1]開始更新

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 100
+ 10; 4 typedef long long ll; 5 struct node 6 { 7 int v, w; 8 node(){} 9 node(int v, int w):v(v), w(w){} 10 }; 11 vector<node>Map[maxn]; 12 int num[maxn];//num[i]表示以i節點為root的子樹中的點的數目 13 int dp[maxn][maxn];//dp[i][j]表示以i節點為root的子樹中只有j條邊最大權值 14 void dfs(int root, int fa) 15 { 16 num[root] = 1
; 17 for(int i = 0; i < Map[root].size(); i++) 18 { 19 int v = Map[root][i].v, w = Map[root][i].w; 20 if(v == fa)continue;//不可回溯 21 dfs(v, root);//先將兒子信息更新好 22 num[root] += num[v];//root子樹中當前的節點數目 23 for(int j = num[root]; j >= 1; j--)//更新父節點的dp 24 {
25 for(int k = 1; k < j && k <= num[v]; k++)//k不能等於j,k=j時說明root的點數目為0 26 dp[root][j] = max(dp[root][j], dp[root][j - k] + dp[v][k] + w); 27 } 28 } 29 } 30 int main() 31 { 32 int n, k; 33 while(scanf("%d%d", &n, &k) != EOF) 34 { 35 memset(dp, 0, sizeof(dp)); 36 for(int i = 1; i < n; i++) 37 { 38 int u, v, w; 39 scanf("%d%d%d", &u, &v, &w); 40 Map[u].push_back(node(v, w)); 41 Map[v].push_back(node(u, w)); 42 } 43 dfs(1, -1); 44 cout<<dp[1][k + 1]<<endl;//包含k條邊,也就是k+1個點 45 } 46 return 0; 47 }

URAL-1018 Binary Apple Tree---樹形DP