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


題目描述

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

輸出格式:

一個數,最多能留住的蘋果的數量。

輸入輸出樣例

輸入樣例:
5 2
1 3 1
1 4 10
2 3 20
3 5 20
輸出樣例:
21

對於樹狀dp,就是在樹上面做動態規划。關鍵點是樹的層次性,而層次性又是有遞歸的建樹而實現的。要注意這題是有根樹,根節點給定是1,而且必須保留!
題解寫到注釋里面了
代碼如下:
 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 #define inf 0x3f3f3f3f
 5 #define M 5000
 6 int next[M],pre[M],last[M],apple[M],dp[M][M],n,m,tot=0;
 7 /*
 8 dp[i][j]表示節點i保留j個枝條的所剩蘋果最大值
 9 apple[i]表示第i條邊上的蘋果數
10 next,pre,last是用來建邊的數組
11 tot來統計邊的序號
12 */
13 void cnct (int u,int v,int w)
14 {
15     tot++;
16     next[tot]=v;
17     pre[tot]=last[u];
18     last[u]=tot;
19     apple[tot]=w;
20 }
21 int dfs (int u,int father)
22 {
23     int ans=0;//ans表示u節點的子節點數目
24     for (int i=last[u];i!=0;i=pre[i])
25     {
26         int v=next[i],value=apple[i];
27         if(v == father)continue;//如果下一個相鄰節點就是父節點,則證明到底層了,開始遞歸父節點的兄弟節點
28         ans+=dfs(v,u)+1;//遞歸到最上層的根節點1
29         for(int j=min(ans,m);j>=1;--j)//因為有限制枝條的數目,取個min
30         {
31             for(int k=min(j,ans);k>=1;--k)
32             dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k-1]+value);
33 /*
34 對於u節點下的子節點j,對j保留多少枝條最優進行dp
35 在這里好好說明下,因為建樹是我們是按照遞歸建的樹。
36 進行比較時,dp[u][j]都是前面選擇除i外的子節點得到的最優解結果
37 所以dp的時候不可能重復或者漏掉某節點
38 */
39         }
40     }
41     return ans;
42 }
43 int main()
44 {
45     //freopen("de.txt","r",stdin);
46     memset(last,0,sizeof last);
47     memset(next,0,sizeof next);
48     memset(pre,0,sizeof pre);
49     memset(dp,0,sizeof dp);
50     scanf("%d%d",&n,&m);
51     for(int i=1;i<n;++i)
52     {
53         int x,y,value;
54         scanf("%d%d%d",&x,&y,&value);
55         cnct(x,y,value);
56         cnct(y,x,value);
57     }
58     dfs(1,0);
59     printf("%d\n",dp[1][m]);
60     return 0;
61 }
62                        

 



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM