刚看到这道题的时候想到了一个用优先队列的贪心思路,大致是统计每个点用魔法消除的贡献,每次删除贡献最大的,删除过程中维护每个点贡献。我觉得蛮对的但是结果甚至过不了样例。
code:
#include<bits/stdc++.h>
#define int long long
#define mk make_pair
using namespace std;
const int N = 2e3 + 7;
int T, n, fa[N], hp[N], sum[N];
vector<int> g[N];
void solve() {
scanf("%d", &n);
for(int i = 1; i <= n; i++) g[i].clear(), sum[i] = 0;
for(int i = 2; i <= n; i++) {
scanf("%d", &fa[i]);
g[fa[i]].push_back(i);
}
for(int i = 1; i <= n; i++)
scanf("%d", &hp[i]);
int ans = 0;
priority_queue<pair<int, int> > q, del;
for(int i = 1; i <= n; i++) {
sum[i] = hp[i];
if(i != 1) sum[i] += hp[i];
ans += hp[i];
for(int v : g[i]) {
sum[i] += hp[v]; ans += hp[v];
}
q.push(mk(sum[i], i));
}
printf("%lld ", ans);
for(int m = 1; m <= n; m++) {
while(!del.empty() && !q.empty() && del.top() == q.top()) {
del.pop(); q.pop();
}
int delt = q.top().first, u = q.top().second; q.pop();
ans -= delt; sum[u] = 0;
printf("%lld", ans); if(m != n) printf(" ");
if(u != 1 && sum[fa[u]] != 0) {
del.push(mk(sum[fa[u]], fa[u]));
sum[fa[u]] -= hp[u];
q.push(mk(sum[fa[u]], fa[u]));
}
for(int v : g[u]) {
if(sum[v] != 0) {
del.push(mk(sum[v], v));
sum[v] -= hp[v];
q.push(mk(sum[v], v));
}
}
}
printf("\n");
// dfs(1);
}
signed main() {
scanf("%d", &T);
while(T --) {
solve();
}
return 0;
}
不是很明白为什么错。求大佬解答。