有一棵蘋果樹,如果樹枝有分叉,一定是分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複製1 3 1
1 4 10
2 3 20
3 5 20
21和選課那題很像啊。
從根節點往下找m條邊使得最後得到的蘋果數最多,最後得到的還得是個完整的樹。
在看本題之前,建議先去看一下p2014 選課。
令dp[i][j]為節點i的子樹上保留j條邊,能保留的最多蘋果數。顯然,在節點i的子樹上保留邊和節點i沒有關係。在選課那一題中,節點i在它的子樹上選擇j門課是包含自身的,因為i是先修課。
所以方程會和選課略有不同:
dp[i][j]=max(dp[i][j],dp[i][j-k-1]+dp[son][k])
答案為dp[1][m]。
#include #include using namespace std;
int n,m,s,head[1001],cnt,dp[1001][1001],value[1001][1001];
bool vis[1001];//用vis陣列記錄判斷父節點跳過的問題也是一樣的
struct node
e[2001];
inline void add(int u,int v,int val)
void dfs(int i,int fa)
} }}signed main()
dfs(1,-1);
cout
}
洛谷P2015 二叉蘋果樹(樹形dp)
有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 3 4 1現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋...
洛谷P2015 二叉蘋果樹 樹形dp)
題目描述 有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 34 1現在這顆樹枝條太多了,需要剪枝。但是一些樹枝...
洛谷P2015 二叉蘋果樹 樹形DP
有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 34 1現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋果...