思维难度不大,在考上上写的启发式合并写错了,只拿了 60 pts,好难过QAQ
Code:
#include <cstdio> #include <algorithm> #include <cstring> #include <set> #include <queue> #define maxn 200001 #define setIO(s) freopen(s".in","r",stdin) ,freopen(s".out","w",stdout) using namespace std; priority_queue<int>Q[maxn]; int edges; int n; int head[maxn],to[maxn],nex[maxn],val[maxn],f[maxn]; void addedge(int u,int v){ nex[++edges] = head[u], head[u] = edges, to[edges] = v; } int tmp[maxn]; int id[maxn]; int idx; void DFS(int u){ id[u]=++idx; for(int v=head[u];v;v=nex[v]){ DFS(to[v]); if(Q[id[u]].size() < Q[id[to[v]]].size()) swap(id[u],id[to[v]]); int m=Q[id[to[v]]].size(); for(int i=1;i<=m;++i) { tmp[i]=max(Q[id[u]].top(),Q[id[to[v]]].top()); Q[id[u]].pop(); Q[id[to[v]]].pop(); } for(int i=1;i<=m;++i) Q[id[u]].push(tmp[i]); } Q[id[u]].push(val[u]); } int main(){ //setIO("spring"); scanf("%d",&n); for(int i = 1;i <= n; ++i) scanf("%d",&val[i]); for(int i = 2;i <= n; ++i) scanf("%d",&f[i]); for(int i = 2;i <= n; ++i) addedge(f[i],i); DFS(1); long long ans = 0; while(!Q[id[1]].empty())ans += (long long)Q[id[1]].top(), Q[id[1]].pop(); printf("%lld\n",ans); return 0; }
luogu P5290 [十二省联考2019]春节十二响 优先队列_启发式合并
原文:https://www.cnblogs.com/guangheli/p/10672929.html