Advanced Guide to Algorithm Competition---0x54 (Tree DP) Prom Without Boss

Topic

Insert picture description here

answer

  1. Classic tree DP problem: we know that the father and son nodes of a tree cannot appear at the same time, then we can get two states, select the parent node and not select the parent node
  1. f[u][0]: select from all subtrees rooted at u, and not select the plan of u point
    f[u][1]: select from all subtrees rooted at u, and select u Point plan
  1. For f[u][0] if this node is not selected, then we have two choices, all of its child nodes can be selected or not, then choose the largest one from these two cases to f[u][ 0]=∑max(f[si,0],f[si,1])
  1. For f[u][1] to select this node, then we cannot select all its child nodes, then there is only one case f[u][1]=∑(f[si,0])

Code

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>

using namespace std;
const int N = 6010;

int n;
int happy[N];
int h[N], e[N], ne[N], idx;  //邻接表存图
int f[N][2];
bool is[N];   //这个点是否父节点

//添加一条a-->b的边
void add(int a, int b) {
    
    
    e[idx] = b;
    ne[idx] = h[a];
    h[a] = idx++;
}

void dfs(int u) {
    
    

    f[u][1] += happy[u];

    for (int i = h[u]; i != -1; i = ne[i]) {
    
    
        int j = e[i];
        dfs(j);
        f[u][0] += max(f[j][0], f[j][1]);
        f[u][1] += f[j][0];
    }
}

int main() {
    
    

    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    memset(h, -1, sizeof h);

    cin >> n;

    for (int i = 1; i <= n; i++) cin >> happy[i];

    for (int i = 1; i < n; i++) {
    
    
        int a, b;
        cin >> a >> b;
        is[a] = true;   //标记此节点不是父节点
        add(b, a);
    }

    int root = 1;
    while (is[root]) root++;

    dfs(root);

    cout << max(f[root][0], f[root][1]) << endl;

    return 0;
}

Guess you like

Origin blog.csdn.net/qq_44791484/article/details/114677850