洛谷P2015 二叉蘋果樹

2022-08-18 22:24:15 字數 1489 閱讀 3560

有一棵蘋果樹,如果樹枝有分叉,一定是分2叉(就是說沒有只有1個兒子的結點)

這棵樹共有n個結點(葉子點或者樹枝分叉點),編號為1-n,樹根編號一定是1。

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

2   5

\ /

3 4

\ /1

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

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

輸入格式:

第1行2個數,n和q(1<=q<= n,1n表示樹的結點數,q表示要保留的樹枝數量。接下來n-1行描述樹枝的資訊。

每行3個整數,前兩個是它連線的結點的編號。第3個數是這根樹枝上蘋果的數量。

每根樹枝上的蘋果不超過30000個。

輸出格式:

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

輸入樣例#1: 複製

5 2

1 3 1

1 4 10

2 3 20

3 5 20

輸出樣例#1: 複製

21

/*

這道題目好難啊!!!!!!!

我這個蒟蒻做了幾個小時也看不懂那個鬼狀態轉移

現在其實也只能略說一二 果然一本通的題目太難啦

(樹形dp)狀態轉移:f[u][j] = max(f[u][j],f[u][j-1-k]+f[v][k]+g[i].v)

真的很難理解:f[i][j]表示結點i保留j條樹枝時留住的蘋果的最大值

v是u的乙個兒子節點 那麼設乙個k 滿足 k<=j-1 表示以v為根的子樹保留的樹枝數 即上面的f[v][k]

f[u][j-1-k]表示的是除了根節點與v連得邊和剛剛的k條邊之外的最大蘋果數

記得還要加上這條邊的蘋果數 即g[i].v

然後呢那裡遍歷j和k時為什麼要逆序呢?其實和01揹包的道理差不多

順序推的話可能會造成重複計算

*/#include

using

namespace

std;

const

int maxn = 105

;int

head[maxn],n,q,size[maxn];

intf[maxn][maxn],cnt;

struct

nodeg[maxn*4

];void addedge(int

from,int to,int

v)void dfs1(int x,int

fa) }

}void dfs2(int x,int

fa) }

}}int

main()

dfs1(

1,0);

dfs2(

1,0);

printf("%d

",f[1

][q]);

return0;

}

洛谷 P2015 二叉蘋果樹

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

洛谷P2015 二叉蘋果樹

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

洛谷P2015 二叉蘋果樹

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