題目描述
有一棵蘋果樹,如果樹枝有分叉,一定是分
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現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋...