小码匠的编程江湖【第80式】:树形DP入门题:没有上司的舞会,多好啊!

2023-08-31 18:32:07 浏览数 (1)

题目描述

某大学有 n 个职员,编号为 1…n。

他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。

现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数,但是呢,如果某个职员的直接上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了。

所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数。

输入格式

输入的第一行是一个整数 n。

第 2 到第(n 1) 行,每行一个整数,第 (i 1) 行的整数表示 i 号职员的快乐指数 r_i。

第 (n 2) 到第 2n 行,每行输入一对整数 l,k,代表 k 是 l 的直接上司。

输出格式

输出一行一个整数代表最大的快乐指数。

输入输出样例

输入 #1

代码语言:javascript复制
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5

输出 #1

代码语言:javascript复制
5
说明/提示
数据规模与约定

对于 100% 的数据,保证 ,,,且给出的关系一定是一棵树。

题目

题目原文请移步下面的链接

  • https://www.luogu.com.cn/problem/P1352
    • 参考题解:https://www.luogu.com.cn/problem/solution/P1352
  • 标签:OI动态规划树形DP

正解

  • 树形dp,设为以i为根的子树能得到的最大快乐指数,同时i不参加舞会,代表i参加时的最大快乐指数
  • 上司参加舞会,则下属可以参加也可以不参加,那么转移方程:
  • 上司参加舞会下属一个都不会参加,此时转移方程:
  • 通过dfs求解答案,同时我们不用建立额外的数组a,可以将的值直接存在里

代码

代码语言:javascript复制
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <bitset>
#include <array>
using namespace std;

struct node {
    int v, next;
} g[6005];

int head[6005], cnt = 0, dp[6005][2], is[6005], vis[6005];

void add(int u, int v) {
    g[  cnt].v = v;
    g[cnt].next = head[u];
    head[u] = cnt;
}

void dfs(int k) {
    vis[k] = 1;
    for (int i = head[k]; i; i = g[i].next) {
        if (vis[g[i].v]) {
            continue;
        }
        dfs(g[i].v);
        dp[k][1]  = dp[g[i].v][0];
        dp[k][0]  = max(dp[g[i].v][0], dp[g[i].v][1]);
    }
    return;
}


void best_coder() {
    int n;
    cin >> n;
    for (int i = 1; i <= n;   i) {
        cin >> dp[i][1];
    }
    for (int i = 1; i < n;   i) {
        int l, k;
        cin >> l >> k;
        is[l] = 1;
        add(k, l);
    }
    for (int i = 1; i <= n;   i){
        if (!is[i]) {
            dfs(i);
            cout << max(dp[i][1], dp[i][0]);
        }
    }
}

void happy_coder() {

}

int main() {
    // 提升cin、cout效率
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    // 小码匠
    best_coder();

    // 最优解
    // happy_coder();

    return 0;
}

0 人点赞