在一棵点有点权的树上,选择一些点,这些点能将所有与它们相连的点覆盖,最终将整棵树上的点全部覆盖,试求最小代价。
刚刚AC了,不过还是对之前90分的代码存有疑问。
下面这份代码只存了每个节点的儿子,而不是存储整个无向图。这样只能拿90分,而改成存储整个无向图再在搜索函数里判断一下son!=fa就满分。两份代码都是不允许往回搜父亲,请问后者比前者多了什么导致AC?
#include <bits/stdc++.h>
using namespace std;
int n, v[1510];
vector <int> G[1510];
int dp[1510][5];//0=self,1=fa,2=son
void sol(int x) {
int sum = 0;
dp[x][0] = v[x]; dp[x][2] = 1e9;
for (int i = 0; i < G[x].size(); i++) {
int y = G[x][i];
sol(y, x);
sum += min(dp[y][0], dp[y][2]);
dp[x][0] += min(dp[y][0], min(dp[y][1], dp[y][2]));
}
dp[x][1] = sum;
for (int i = 0; i < G[x].size(); i++) {
int y = G[x][i];
dp[x][2] = min(dp[x][2], sum - min(dp[y][2], dp[y][0]) + dp[y][0]);
}
}
int main() {
ios::sync_with_stdio(0);
cin >> n;
int x, k, m;
for (int i = 0; i < n; i++) {
cin >> x >> k >> m;
v[x] = k;
for (int j = 0; j < m; j++) {
cin >> k; G[x].push_back(k);
}
}
sol(1, 0);
cout << min(dp[1][0], dp[1][2]);
}