問題描述
有一棵 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的正整數。
樹形dp來解決
dp[i][j] 節點i j=0為選取,j=1為不選
dp[i][0] += max(dp[q][0],dp[q][1])
dp[i][1] += dp[q][0];
我們倒著來,從子節點開始,最後輸出max(dp[1][0],dp[1][1])
建個樹開始dfs即可
#include
#include
#include
#include
#include
#include
#include
using namespace std;
struct node
edge[200020];
int head[100010];
int dp[100010][2];
int m;
void addedge(int from,int to)
void dfs(int x,int pre)
dfs(v,x);
dp[x][1]+=dp[v][0];
dp[x][0]+=max(dp[v][0],dp[v][1]);}}
int main()
for(int i=1;i>a>>b;
addedge(a,b);
}dfs(1,-1);
cout<>n;
while(n--)
if(str[i]=='1')
if(str[i]=='2')
if(str[i]=='3')
if(str[i]=='4')
if(str[i]=='5')
if(str[i]=='6')
if(str[i]=='7')
if(str[i]=='8')
if(str[i]=='9')
if(str[i]=='a')
if(str[i]=='b')
if(str[i]=='c')
if(str[i]=='d')
if(str[i]=='e')
if(str[i]=='f')
}int shuchu=0;
int sum;
int t;
len=str2.length();
for(int i=0;i=0;i--)
for(int j=i;j>=0;j--)
cout<}}*/
演算法訓練 結點選擇 (樹形dp)(點權)
問題描述 有一棵 n 個節點的樹,樹上每個節點都有乙個正整數權值。如果乙個點被選擇了,那麼在樹上和它相鄰的點都不能被選擇。求選出的點的權值和最大是多少?輸入格式 第一行包含乙個整數 n 接下來的一行包含 n 個正整數,第 i 個正整數代表點 i 的權值。接下來一共 n 1 行,每行描述樹上的一條邊。...
樹形DP 結點選擇
問題描述 有一棵 n 個節點的樹,樹上每個節點都有乙個正整數權值。如果乙個點被選擇了,那麼在樹上和它相鄰的點都不能被選擇。求選出的點的權值和最大是多少?輸入格式 第一行包含乙個整數 n 接下來的一行包含 n 個正整數,第 i 個正整數代表點 i 的權值。接下來一共 n 1 行,每行描述樹上的一條邊。...
演算法訓練 結點選擇 樹形動態規劃
問題描述 有一棵 n 個節點的樹,樹上每個節點都有乙個正整數權值。如果乙個點被選擇了,那麼在樹上和它相鄰的點都不能被選擇。求選出的點的權值和最大是多少?輸入格式 第一行包含乙個整數 n 接下來的一行包含 n 個正整數,第 i 個正整數代表點 i 的權值。接下來一共 n 1 行,每行描述樹上的一條邊。...