演算法訓練 結點選擇 樹形DP

2021-08-11 14:23:06 字數 1690 閱讀 3643

問題描述

有一棵 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 行,每行描述樹上的一條邊。...