題目鏈結
題意: 給定一棵樹,每條邊有權重,問如果只保留e條邊,最多能保留多大權重
保留e條邊,不容易分析,轉化成保留e+1個點,權重放給孩子節點 問題轉化成 保留包括根節點在內的e+1個節點,求最大權重和
建樹方式:鏈式前向星,建雙邊
由此轉化成樹上01揹包問題
//dp[rt][m] 以rt為根,保留根節點在內的m個點的最優解,父節點的最優解由孩子節點遞推而來,邊界就是葉子節點 葉子->根
每個孩子回溯時,對於以孩子節點為根的子樹來說,只有選它和不選兩種
dp[rt][j]=max(dp[rt][j],dp[to][k]+dp[rt][j-k]) 不選 和選 列舉k即可
其餘細節見注釋
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace std;
#define ll long long
#define ull unsigned long long
const
int inf=
3000
;const
double eps=
1e-5
;const
int maxn=
2e2+50;
//二叉蘋果樹 給定一棵樹,每條邊有權重,問如果只保留e條邊,最多能保留多大權重
//樹形dp,關鍵點是如何建樹以及如何dp,如何dp決定了如何建樹,所以先分析如何dp
//保留e條邊,不容易分析,轉化成保留e+1個點,權重放給孩子節點 問題轉化成 保留包括根節點在內的e+1個節點,求最大權重和
//由此轉化成樹上揹包問題
//dp[rt][m] 以rt為根,保留根節點在內的m個點的最優解,父節點的最優解由孩子節點遞推而來,邊界就是葉子節點
//對於每個孩子 只有選和不選兩種情況
//dp[rt][j]=max(dp[rt][j],dp[to][k]+dp[rt][j-k]) 列舉k即可
struct
edge[maxn]
;int cnt=
1,head[maxn]
;void
add(
int from,
int to,
int w)
int n,e;
int dp[maxn]
[maxn]
;//以rt為根的樹 選包括根在內的j個頂點 最大價值
intdfs
(int rt,
int par)}}
return sum;
}int
main()
dfs(1,
-1);
printf
("%d\n"
,dp[1]
[e+1])
;system
("pause");
return0;
}
P2015 二叉蘋果樹(樹上揹包)
有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 3 4 1 現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有...
P2015二叉蘋果樹 (樹上DP)
p2015 二叉蘋果樹 提交15.30k 通過7.27k 時間限制 1.00s 記憶體限制 125.00mb 提交答案 加入收藏 題目提供者 洛谷難度 普及 提高 歷史分數 100提交記錄 檢視題解 標籤進入討論版 相關討論 推薦題目 展開題目描述 有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說...
P2015 二叉蘋果樹
這道題的dp還是先更新子節點,在更新父節點,不過問題就是怎樣更新他們 我們定義ff i j 為第i個節點字數上共保留j條邊的情況下最多的蘋果數,對於每乙個點,他保留的邊必然是他直接保留的之前保留的邊和他當前兒子保留的邊的值的和加上這一條邊的 邊權,即ff u i max ff u i f u i j...