問題描述
有一棵 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 個正整數,...