樹形DP 藍橋杯 ALGO 4 結點選擇

2021-08-17 10:00:42 字數 1320 閱讀 9072

問題描述

有一棵 n 個節點的樹,樹上每個節點都有乙個正整數權值。如果乙個點被選擇了,那麼在樹上和它相鄰的點都不能被選擇。求選出的點的權值和最大是多少?

輸入格式

第一行包含乙個整數 n 。

接下來的一行包含 n 個正整數,第 i 個正整數代表點 i 的權值。

接下來一共 n-1 行,每行描述樹上的一條邊。

輸出格式

輸出乙個整數,代表選出的點的權值和的最大值。

樣例輸入5

1 2 3 4 5

1 21 3

2 42 5

樣例輸出

12樣例說明

選擇3、4、5號點,權值和為 3+4+5 = 12 。

資料規模與約定

對於20%的資料, n <= 20。

對於50%的資料, n <= 1000。

對於100%的資料, n <= 100000。

權值均為不超過1000的正整數。

【題意】

遍歷整棵樹,求選出的點的權值和的最大值。

【型別】

樹形動態規劃

【演算法思路】

本題型別是一道樹形動態規劃,這裡在dfs中選擇乙個葉子節點開始自下向上進行運算,是因為如果按常規的想法若是從樹的根開始向下遞迴  但是這個時候就要判斷他的兩個子節點是否被選上。 相反,若以葉子節點開始,就不必判斷兩個點了,直接判斷他的父親節點選還是不選,。為使得值最大,若從葉子節點開始效率更高一些。   

對於每乙個節點只有兩種可能,即是選上或者是不選上,所以就建立乙個二維陣列,比如dp[n][2], 這裡n表示節點數目,而後面2表示每個節點就兩種選擇,所以dp[i][0]表示第i個節點不選時的權值,而dp[i][1]表示第i個節點擊上時的權值,便可以開始逆推了

其中,dfs(int u,int f)分別表示起始節點u和某一父節點f,f節點時讓dfs終止的標誌位節點。

#include #include#include#includeusing namespace std;

const int nmax=10001;

vectorg[nmax];//鄰接表

int dp[nmax][2];//v[i][0]與v[i][1] 表示第i個節點擊或者不選的時候所對應的value

//通過遍歷整棵樹,計算符合條件的value值

int dfs(int u,int f)

//初始化鄰接表,建立父節點與子節點之間的邊

for(int i=1;i>u>>v;

g[u].push_back(v);

g[v].push_back(u);

} int ans;

/*for(int i=0;i

藍橋杯ALGO 4演算法訓練 結點選擇(樹形DP)

問題描述 有一棵 n 個節點的樹,樹上每個節點都有乙個正整數權值。如果乙個點被選擇了,那麼在樹上和它相鄰的點都不能被選擇。求選出的點的權值和最大是多少?輸入格式 第一行包含乙個整數 n 接下來的一行包含 n 個正整數,第 i 個正整數代表點 i 的權值。接下來一共 n 1 行,每行描述樹上的一條邊。...

藍橋杯 ALGO 4 結點選擇

演算法訓練 結點選擇 時間限制 1.0s 記憶體限制 256.0mb 問題描述 有一棵 n 個節點的樹,樹上每個節點都有乙個正整數權值。如果乙個點被選擇了,那麼在樹上和它相鄰的點都不能被選擇。求選出的點的權值和最大是多少?輸入格式 第一行包含乙個整數 n 接下來的一行包含 n 個正整數,第 i 個正...

藍橋杯 演算法訓練 ALGO 4 結點選擇

本人是乙個剛剛接觸c 不久的傻學生 記錄一些自己的學習過程。大神路過可以批評指正 問題描述 有一棵 n 個節點的樹,樹上每個節點都有乙個正整數權值。如果乙個點被選擇了,那麼在樹上和它相鄰的點都不能被選擇。求選出的點的權值和最大是多少?輸入格式 第一行包含乙個整數 n 接下來的一行包含 n 個正整數,...