树形 DP:打家劫舍III【基础算法精讲 24】_哔哩哔哩_bilibili 

思路参考,讲得非常清晰。

树形dp acwing 285. 没有上司的舞会_#include

树中选不相邻节点,取值最大:

dfs返回两个数,第一个数表示选root的最大值,第二个数表示不选root的最大值。

vector<int>dfs(root): 
    vector<int>v;
   v[0] = root.val;
    for i root的子节点:
           v[0]+=dfs(i)[1];   v[1] += max( dfs(i)[0] , dfs(i)[1] );
   return v;
res= max( dfs(root) [0] ,  dfs(root) [1] );
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

树形dp acwing 285. 没有上司的舞会_算法_02

代码:

#include<iostream>
#include<string>
#include<vector>
using namespace std;
int N;
int H[6001];
vector<vector<int>>g;
int L,K;

bool has_father[6001];
vector<int> dfs(int root){
    vector<int>res(2,0);
    res[0]=H[root];
    for(auto ne:g[root]){
        vector<int>c = dfs(ne);
        res[0]+=c[1];
        res[1]+=max(c[1],c[0]);
    }
    return res;
}
int main(){
    cin>>N;
    g.resize(N+1);
    for(int i=1;i<=N;i++){
        cin>>H[i];
    }
    for(int i=1;i<=N-1;i++){
        cin>>L>>K;
        has_father[L]=true;
        g[K].push_back(L);
    }
    int root=1;
    while(has_father[root])root++;
    vector<int>v = dfs(root);
    cout<<max(v[0],v[1]);
    return 0;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.