藍橋杯 演算法訓練 ALGO 4 節點擊擇

2021-08-15 16:57:52 字數 1389 閱讀 5729

問題描述

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

輸入格式

第一行包含乙個整數 n 。

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

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

輸出格式

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

樣例輸入

51 2 3 4 5

1 2

1 3

2 4

2 5

樣例輸出

12樣例說明

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

資料規模與約定

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

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

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

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

思路:用f[i]表示從子樹i中選擇結點,且結點i必須被選擇的最大值,用g[i]表示從子樹i中選擇結點,且結點i必須不被選擇的最大值。

則f[i]=pow[i]+\sum(g[j]),其中pow[i]表示結點i的權值,j是i的子結點,\sum(g[j])表示所有g[j]的和。

g[i]=\sum(max(f[j], g[j])),其中j是i的子結點。

最後輸出f[p],g[p]中較大的數即為答案,p為樹的根節點,這道題裡任何一點都可以視為根節點。

#include #includeusing namespace std;

const int e=100100;

int f[e],g[e],visited[e];

int pow[e];

struct child

;//用鄰接表儲存

child *a[e];//a[i]鍊錶記錄了i結點的所有相鄰結點

void tree(int u,int v)

void dfs(int v)//執行dfs(i)會得到f[i]和g[i]的值

} f[v]+=pow[v-1];//記得加上pow的值

}int main()

//輸入

memset(a,null,sizeof(a));

memset(visited,0,sizeof(visited));

memset(f,0,sizeof(f));

memset(g,0,sizeof(g)); //初始化

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

tree(u,v);//記錄u,v結點的資訊

} dfs(1);//可以將結點1視為根節點,然後深搜

cout<}

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

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

藍橋杯 ALGO 4 結點選擇

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

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

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