標籤:typedef its memset 有一個 main c++ namespace ace ref
題目連結:
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--)//更新父節點的dp24 {25 for(int k = 1; k < j && k <= num[v]; k++)//k不能等於j,k=j時說明root的點數目為026 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