AcWing 10. 有依赖的背包问题 (java dfs序 O(nV))
原题链接
困难
作者:
11111_0
,
2020-09-16 02:12:36
,
所有人可见
,
阅读 678
时间复杂度 $O(nV)$
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) {
solve();
}
static int size[];
static List<Integer> list;
private static void solve() {
int n = IN.nextInt(), V = IN.nextInt(), vs[] = new int[n + 1], ws[] = new int[n + 1];
init(n);
int fa, root = -1;
for (int i = 1; i <= n; i++) {
vs[i] = IN.nextInt();
ws[i] = IN.nextInt();
if ((fa = IN.nextInt()) == -1) {
root = i;
} else {
add(fa, i);
}
}
dfs(root);
int dp[][] = new int[n + 1][V + 1], cur;
for (int i = 1; i <= n; i++) {
cur = list.get(i - 1);
for (int j = V; j >= 0; j--) {
// 若不选物品i,则也不可以选它的子树
dp[i][j] = dp[i - size[cur]][j];
if (j >= vs[cur]) {
// 若选了物品i,则可以选它的子树
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - vs[cur]] + ws[cur]);
}
}
}
System.out.println(dp[n][V]);
}
public static void dfs(int cur) {
size[cur] = 1;
for (int i = head[cur]; i != 0; i = next[i]) {
dfs(to[i]);
size[cur] += size[to[i]];
}
list.add(cur);
}
static int head[], next[], to[], id = 1;
public static void init(int n) {
head = new int[n + 2];
next = new int[n + 2];
to = new int[n + 2];
list = new ArrayList<>(n + 1);
size = new int[n + 1];
}
public static void add(int f, int t) {
next[id] = head[f];
head[f] = id;
to[id++] = t;
}
static class IN {
private static final BufferedReader br = new BufferedReader(new InputStreamReader(System.in), 65535);
private static StringTokenizer st = null;
public static int nextInt() {
while (st == null || !st.hasMoreTokens()) {
try {
st = new StringTokenizer(br.readLine());
} catch (Exception e) {
break;
}
}
return Integer.valueOf(st.nextToken());
}
}
}