本人是乙個剛剛接觸c++不久的傻學生~記錄一些自己的學習過程。大神路過可以批評指正~
問題描述
有一棵 n 個節點的樹,樹上每個節點都有乙個正整數權值。如果乙個點被選擇了,那麼在樹上和它相鄰的點都不能被選擇。求選出的點的權值和最大是多少?
輸入格式
第一行包含乙個整數 n 。
接下來的一行包含 n 個正整數,第 i 個正整數代表點 i 的權值。
接下來一共 n-1 行,每行描述樹上的一條邊。
輸出格式
輸出乙個整數,代表選出的點的權值和的最大值。
樣例輸入
51 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的正整數。
解題:一道基本的樹形動態規劃題目。
dp[x][0]表示x結點不選中時最大的權值,dp[x][1]表示x結點擊中時最大的權值
狀態轉移方程:dp[x][1] = dp[x][1] + dp[u][0] (u為x的子結點)
dp[x][0] = dp[x][0] + max(u為x的子結點)
**如下:
#include#include#include
using
namespace
std;
#define max(a,b) a>b?a:b
const
int maxn = 100001
;int m; //
表示邊的索引號,初始為0
int head[maxn]; //
表示某個結點所連線的邊
int dp[maxn][2]; //
dp[x][0]表示第x個結點不選擇時最大權值,dp[x][1]表示第x個結點選擇時最大權值
struct
edgeedge[2*maxn]; //
一共有n個結點,有n-1條邊,但是不同的出發結點算作不同的邊,所以有2n-2條邊
//把新邊加入邊集,構造樹
void add(int
from, int
to)//
類似dfs遍歷
void dfs(int node, int
prenode)
}int
main()
for (int j = 1; j <= n - 1; j++)
dfs(
1, 0); //
從1號結點開始向後動態規劃
int result = max(dp[1][0], dp[1][1]); //
因為不確定根結點,所以從幾號開始動態規劃就找幾號的狀態
//同樣這裡也可以寫成 dfs(2, 0); int result = max(dp[2][0], dp[2][1]);不過當只有乙個結點的時候就不對了
cout << result
}
藍橋杯 ALGO 4 結點選擇
演算法訓練 結點選擇 時間限制 1.0s 記憶體限制 256.0mb 問題描述 有一棵 n 個節點的樹,樹上每個節點都有乙個正整數權值。如果乙個點被選擇了,那麼在樹上和它相鄰的點都不能被選擇。求選出的點的權值和最大是多少?輸入格式 第一行包含乙個整數 n 接下來的一行包含 n 個正整數,第 i 個正...
藍橋杯ALGO 4演算法訓練 結點選擇(樹形DP)
問題描述 有一棵 n 個節點的樹,樹上每個節點都有乙個正整數權值。如果乙個點被選擇了,那麼在樹上和它相鄰的點都不能被選擇。求選出的點的權值和最大是多少?輸入格式 第一行包含乙個整數 n 接下來的一行包含 n 個正整數,第 i 個正整數代表點 i 的權值。接下來一共 n 1 行,每行描述樹上的一條邊。...
藍橋杯 演算法訓練 ALGO 4 節點擊擇
問題描述 有一棵 n 個節點的樹,樹上每個節點都有乙個正整數權值。如果乙個點被選擇了,那麼在樹上和它相鄰的點都不能被選擇。求選出的點的權值和最大是多少?輸入格式 第一行包含乙個整數 n 接下來的一行包含 n 個正整數,第 i 個正整數代表點 i 的權值。接下來一共 n 1 行,每行描述樹上的一條邊。...