【算法竞赛进阶指南】CH5401/洛谷p1352 - 没有上司的舞会 - 树形dp模板题

题目描述 

Ural大学有N名职员,编号为1~N。

他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。

每个职员有一个快乐指数,用整数 HiHi 给出,其中 1≤i≤N1≤i≤N。

现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。

在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。

输入格式

第一行一个整数N。

接下来N行,第 i 行表示 i 号职员的快乐指数HiHi。

接下来N-1行,每行输入一对整数L, K,表示K是L的直接上司。

输出格式

输出最大的快乐指数。

数据范围

1 ≤ N ≤ 6000,
−128 ≤ Hi ≤ 127

输入样例:

7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5

输出样例:

5
难度:简单
时/空限制:1s / 64MB
来源:《算法竞赛进阶指南》, 模板题

题目分析:

这题其实和大盗阿福 没差别,只是线性结构变成树形结构,只要O(n)找下根节点,然后从根节点到叶节点dfs一下即可

代码:

#include <iostream>
#include <cstring>
using namespace std;
const int N = 6e3 + 10;
int f[N][2];
int h[N], st[N];
int head[N], nex[N], edge[N], tot;
void add(int u, int v){
    edge[++ tot] = v;
    nex[tot] = head[u];
    head[u] = tot;
}
void dfs(int u){
    f[u][1] = h[u];
    for (int i = head[u]; ~i; i = nex[i]){
        int v = edge[i];
        dfs(v);
        f[u][0] += max(f[v][0], f[v][1]);
        f[u][1] += f[v][0];
    }
}
int main()
{
    memset(head, -1, sizeof(head));
    int n;
    cin >> n;
    for (int i = 1; i <= n; ++ i) cin >> h[i];
    int u, v;
    for (int i = 1; i < n; ++ i){
        cin >> u >> v;
        add(v, u);
        st[u] = 1;
    }
    int root = 1;
    while (st[root]) ++ root;
    dfs(root);
    cout << max(f[root][0], f[root][1]) << endl;
    return 0;
}

 

发布了21 篇原创文章 · 获赞 0 · 访问量 826

猜你喜欢

转载自blog.csdn.net/tourist1412/article/details/104983506