[十二省聯考2019]春節十二響
阿新 • • 發佈:2019-04-28
line clas names push_back ont www string swap top
[十二省聯考2019]春節十二響
考場上最簡單的一道題,可惜我沒有想到合並(明明鏈都打出來了)
直接維護堆的啟發式合並就好了
#include<cstdio> #include<cstring> #include<iostream> #include<cctype> #include<vector> #include<queue> #include<set> #include<algorithm> using namespace std; const int N = 2e5 + 3; vector <int> G[N]; priority_queue <int> q[N]; int n,t; int w[N],fa[N]; int rt[N]; int s[N]; int tot = 0; inline int read(){ int v = 0,c = 1;char ch = getchar(); while(!isdigit(ch)){ if(ch == '-') c = -1; ch = getchar(); } while(isdigit(ch)){ v = v * 10 + ch - 48; ch = getchar(); } return v * c; } inline void dfs(int x){ vector <int> need; if(!rt[x]) rt[x] = ++t; for(int i = 0;i < (int)G[x].size();++i){ int y = G[x][i]; if(y == fa[x]) continue; dfs(y); if(q[rt[y]].size() > q[rt[x]].size()) swap(rt[x],rt[y]); // printf("%d %d\n",q[rt[y]].size() ,q[rt[x]].size() ); for(;!q[rt[y]].empty();q[rt[x]].pop(),q[rt[y]].pop()) need.push_back(max(q[rt[x]].top(),q[rt[y]].top())); for(int i = 0;i < (int)need.size();++i) q[rt[x]].push(need[i]); need.clear(); } q[rt[x]].push(w[x]); } int main(){ n = read(); for(int i = 1;i <= n;++i) w[i] = read(); for(int i = 2;i <= n;++i){ fa[i] = read(); G[fa[i]].push_back(i); G[i].push_back(fa[i]); } dfs(1); long long ans = 0; for(;!q[rt[1]].empty();q[rt[1]].pop()) ans += q[rt[1]].top(); printf("%lld\n",ans); return 0; }
[十二省聯考2019]春節十二響