Files
python/TangDou/AcWing/BeiBao/10_DfsOrder.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

69 lines
2.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
const int N = 110;
// 邻接表
int h[N], ne[N], e[N], idx;
void add(int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
int n, m; // n个物品,m个空间上限
int v1[N], w1[N], v[N], w[N]; // 因为在生成 dfs序的过程中,本质是重新将原来的输入次序重排了,需要记录原来的体积、价值,和新的体积、价值
int f[N][N]; // 表示在以u为根的子树中,用大小为j的包能取得的最大价值
int sz[N]; // 以i为根结点的子树中结点的个数
int dfn[N], ts; // 时间戳
/**
* 功能:dfs序
* 本质:就是执行一遍树的dfs,找一个辅助数组记录一下dfs序
* @param u 结点编号
*/
void dfs(int u) {
dfn[u] = ++ts; // 记录结点u在dfs序中是第几个,下标从1开始,时间戳
// 维护子树的结点个数
sz[ts] = 1; // 以dfs序中ts号为根的子树中结点个数
w[ts] = w1[u]; // 将原来树中p号结点的体积转移到ts号dfs序的结点体积上去
v[ts] = v1[u]; // 将原来树中p号结点的价值转移到ts号dfs序的结点价值上去
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
dfs(j);
// 收集所有子结点的个数
sz[dfn[u]] += sz[dfn[j]];
}
}
int main() {
// 初始化
memset(h, -1, sizeof h);
cin >> n >> m;
int root;
for (int i = 1; i <= n; i++) {
int p;
cin >> w1[i] >> v1[i] >> p;
if (p == -1)
root = i; // 记录根结点
else
add(p, i); // 维护邻接表
}
// dfs序
dfs(root);
// 倒着做01背包
for (int i = n; i >= 1; i--)
for (int j = 1; j <= m; j++) {
f[i][j] = f[i + sz[i]][j]; // 放弃物品i
if (j >= w[i]) f[i][j] = max(f[i][j], f[i + 1][j - w[i]] + v[i]); // 选择物品i
}
// 输出
printf("%d\n", f[1][m]);
return 0;
}