题目链接
思考
首先本题中的关系是一种树形结构,而且符号最优子结构和无后效性,所以可以进行记忆化搜索。
那么首先要在这颗树中选出一个点作为根节点,按照习惯我们将没有父节点的点作为根节点。
接下来要思考的是 状态:
dp[i][0]表示不选i时,以i为根子树的最大权值。
dp[i][1]表示选i时,以i为根子树的最大权值。
dp[i][0]+=max(dp[j][0],dp[j][1])
dp[i][1]+=dp[j][0]
j是i的儿子,所以首先要dfs到子叶,最后输出的时候 比较一下 max(dp[i][1],dp[i][0])
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <vector> 5 #include <string> 6 using namespace std; 7 vector<int>G[10005]; 8 int father[10005],dp[10005][3],a[10005],n; 9 10 void dfs(int k){ 11 for(int i=0;i < G[k].size();i++){ 12 int h = G[k][i]; 13 dfs(h); 14 dp[k][0] += max(dp[h][1],dp[h][0]); 15 dp[k][1] += dp[h][0]; 16 } 17 dp[k][1]+=a[k]; 18 } 19 int main(){ 20 scanf("%d",&n); 21 for(int i=1;i<=n;i++){ 22 scanf("%d",&a[i]); 23 } 24 for(int i=1;i<=n;i++){ 25 int x,y; 26 scanf("%d%d",&x,&y); 27 if(!x && !y) break; 28 G[y].push_back(x); 29 father[x] = y; 30 } 31 for(int i=1;i<=n;i++){ 32 if(!father[i]){ 33 dfs(i); 34 printf("%d",max(dp[i][0],dp[i][1])); 35 break; 36 } 37 } 38 return 0; 39 }