1. 程式人生 > 其它 >基礎演算法學習---樹狀dp

基礎演算法學習---樹狀dp

沒有上司的舞會

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 6010;

int hp[N];
int e[N],h[N],ne[N],idx;
int f[N][2];
bool hf[N];
int n;

//鄰接表建樹
void add(int a,int b){
    e[idx] = b;
    ne[idx] = h[a];
    h[a] = idx ++;
}

void dfs(int u){
    //dp賦值
    f[u][1] = hp[u];

    //遍歷子節點
    for(int i = h[u];i != -1;i = ne[i]){
        int j = e[i];
        //子節點更新
        dfs(j);

        //選不選父節點
        f[u][1] += f[j][0];
        f[u][0] += max(f[j][1],f[j][0]);
    }
}

int main(){
    cin >> n;

    for(int i = 1;i <= n;i ++) cin >> hp[i];
    memset(h,-1,sizeof h);

    for(int i = 1;i < n;i ++){
        int a,b;
        cin >> a >> b;

        //b為a的父親
        add(b,a);
        hf[a] = 1;
    }

    //找根節點
    int rt = 1;
    while(hf[rt]) rt ++;

    //根節點開搜
    dfs(rt);

    cout << max(f[rt][0],f[rt][1]);
}