P2015二叉蘋果樹 (樹上DP)

2021-10-08 21:46:54 字數 2006 閱讀 6711

p2015 二叉蘋果樹

提交15.30k

通過7.27k

時間限制

1.00s

記憶體限制

125.00mb

提交答案

加入收藏

題目提供者

洛谷難度

普及/提高-

歷史分數

100提交記錄 檢視題解

標籤進入討論版

相關討論

推薦題目

展開題目描述

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

1 4 10

2 3 20

3 5 20

輸出 #1複製

21

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

typedef

long

long ll;

typedef

unsigned

long

long ull;

#define rep(i,a,b) for(int i=a;i<=b;i++)

#define per(i,a,b) for(int i=a;i>=b;i--)

#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

template

<

typename t>

void

write

(t x)

if(x>9)

putchar

(x%10

+'0');

}template

<

typename t>

void

read

(t &x)

while

(isdigit

(ch))x*

=f;}

const

int maxn=

150;

int head[maxn]

,dp[maxn]

[maxn]

;int n,m,a,b,c;

struct nodee[maxn*2]

;int tot,sz[maxn]

;void

add(

int u,

int v,

int w)

void

dfs(

int u,

int fa)}}

}int

main()

dfs(1,

0);write

(dp[1]

[m])

;return0;

}

P2015 二叉蘋果樹

這道題的dp還是先更新子節點,在更新父節點,不過問題就是怎樣更新他們 我們定義ff i j 為第i個節點字數上共保留j條邊的情況下最多的蘋果數,對於每乙個點,他保留的邊必然是他直接保留的之前保留的邊和他當前兒子保留的邊的值的和加上這一條邊的 邊權,即ff u i max ff u i f u i j...

P2015 二叉蘋果樹

題面 設f u i 表示u的子樹上保留i條邊,至多保留的蘋果數目 那麼狀態轉移方程也就顯而易見了 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的子樹上的...

P2015 二叉蘋果樹

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