1002 没有上司的舞会 dfs 树形DP

链接:https://ac.nowcoder.com/acm/contest/25022/1002
来源:牛客网

题目描述

Ural大学有N名职员,编号为1~N。
他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。
每个职员有一个快乐指数,用整数 HiHi 给出,其中 1≤i≤N,1≤i≤N1\leq i\leq N,1\leq i\leq N1iN,1iN。
现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。
在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。


输入描述:

第一行一个整数N。
接下来N行,第 i 行表示 i 号职员的快乐指数Hi。
接下来N-1行,每行输入一对整数L, K,表示K是L的直接上司。
最后一行输入0,0。

输出描述:

输出最大的快乐指数。
示例1

输入

复制
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0

输出

复制
5

备注:

1≤N≤6000,1\leq N\leq 6000,1N6000,
−128≤Hi≤127−128\leq H_i\leq 127128Hi127

 

分析

设dp[i][2] dp[i][1] 表示以i为根节点,选择i的最大快乐指数,dp[i][0]表示以i为根节点,不选择i的最大快乐指数

状态转移:dp[i][0] += max(dp[g[i][j]][0],dp[g[i][j]][1]) 。不选择的要加上所有子节点选择或者不选择的最大值

选择的要加上所有子节点不选择的情况,最后还要加上本身的快乐指数。

    

//-------------------------代码----------------------------

//#define int ll
const int N = 2e6+10;
int n,m;
int h[N];
int f[N][2];

void dfs(int p,int fa,V<int> g[]) {
    
    for(int i = 0;i<g[p].size();i++) {
        if(g[p][i] == fa) continue;
        dfs(g[p][i],p,g);
        f[p][0] += max(f[g[p][i]][0],f[g[p][i]][1]);
        f[p][1] += f[g[p][i]][0];
    }
    f[p][1] += h[p];
    
}

void solve()
{
    cin>>n;
    V<bool> vis(n+1);
    V<int> g[n+1];
    fo(i,1,n) cin>>h[i];
    fo(i,1,n-1) {
        int l,k;
        cin>>l>>k;
        g[k].pb(l);
        vis[l] = 1;
    }
    int laji;cin>>laji>>laji;
    int root;
    fo(i,1,n) {
        if(vis[i] == 0) {
            root = i;
            break;
        }
    }
    dfs(root,-1,g);
    cout<<max(f[root][0],f[root][1])<<endl;
}

signed main(){
    clapping();TLE;

//    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

 

posted @ 2022-08-01 14:33  er007  阅读(7)  评论(0编辑  收藏  举报