樹形DP依賴揹包 洛谷 P2015 二叉蘋果樹

2021-08-28 18:31:00 字數 2085 閱讀 2258

題目描述

有一棵蘋果樹,如果樹枝有分叉,一定是分

2叉(就是說沒有只有

1個兒子的結點)

這棵樹共有

n個結點(葉子點或者樹枝分叉點),編號為

1-n,

樹根編號一定是1。

我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有

4個樹枝的樹

2   5

\ /

3   4

\ / 1

現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋果。

給定需要保留的樹枝數量,求出最多能留住多少蘋果。

輸入輸出格式

輸入格式:第1

行2個數,n

和q(1<=q<= n,1。 n

表示樹的結點數,

q表示要保留的樹枝數量。接下來

n-1行描述樹枝的資訊。 每行

3個整數,前兩個是它連線的結點的編號。第

3個數是這根樹枝上蘋果的數量。

每根樹枝上的蘋果不超過

30000個。

輸出格式:

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

輸入輸出樣例

輸入樣例#1複製

5 21 3 1

1 4 10

2 3 20

3 5 20

輸出樣例#1複製 21

演算法分析:

但與上一題有所不同,

1.這題明確給出根節點為1,所以不會是上一題的無根樹

2.父節點和子結點不像上一題一樣標準的給出,所以每乙個結點就沒有了明確的值。

3.這題要求刪邊對應上一題刪點數目+1

這題遇上題一模一樣,但是這題目沒給標準的給你父節點和子節點,但在後面給你乙個價值,這時候你不確定子節點是誰,所以值不能想上一題一樣直接複製子節點,所以vextor就不好入手了,所以建樹時要注意。

這就需要完整的鏈式向前星,需要儲存邊的值,在建好樹後,賦值給對應的子節點。

#include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std;

const int n=310;

struct node

edge[n*2];///無向邊,2倍

int head[n];///head[u]=i表示以u為起點的所有邊中的第一條邊是 i號邊

int tot; ///總邊數

int minn;

void add(int u,int v,int w)

int n,m;

int dp[n][n],val[n];

void dfs(int u,int fa)

edge[n*2];///無向邊,2倍

int head[n];///head[u]=i表示以u為起點的所有邊中的第一條邊是 i號邊

int tot; ///總邊數

void add(int u,int v,int w)

int n,m;

int dp[n][n];

///dp[i][j]表示節點i保留j個枝條的所剩蘋果最大值

int dfs(int u,int fa)

} return num;

}int main()

dfs(1,-1);

printf("%d\n",dp[1][m]);

return 0;

}

樹形DP 模版題 p2015

狀態轉移方程也就顯而易見了 f u i max f u i f u i j 1 f v j e i w 1 i min q,sz u 0 j min sz v i 1 u表示當前節點,v是u的乙個子節點,sz u 表示u的子樹上的邊數,q就是題目中要求的最多保留邊數 include include ...

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

給出乙個n個點的二叉樹,樹上有邊權,求留下q個樹枝能夠獲得的最大收益為多少。dp i j d p i j 表示在以 i i 為根的節點,留下 j role presentation j j個分支,的最大收益值。設u u 為當前遍歷到的根節點,v role presentation v v為訪問的子節...

洛谷 P2015 二叉蘋果樹 樹形dp

有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 3 4 1現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋...