标签:return scanf while its open amp 时间复杂度 close +=
首先可以发现对于两条链来说,显然是对两边都排好序,然后大的配大的,小的配小的(正确性比较显然),最后再加入根(根只能单独选)
这个结果其实也可以理解为将所有max构成一条新的链,求出
因此,对于每一个结点计算出答案,然后与别的点合并得到父亲,用启发式合并+set时间复杂度为两个log。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 200005 4 struct ji{ 5 int nex,to; 6 }edge[N]; 7 priority_queue<int>qq,q[N]; 8 int E,n,x,y,a[N],f[N],head[N]; 9 long long ans; 10 void add(int x,int y){ 11 edge[E].nex=head[x]; 12 edge[E].to=y; 13 head[x]=E++; 14 } 15 int top(priority_queue<int>&q){ 16 int k=q.top(); 17 q.pop(); 18 return k; 19 } 20 void dfs(int k){ 21 for(int i=head[k];i!=-1;i=edge[i].nex){ 22 int v=edge[i].to; 23 dfs(v); 24 if (q[f[k]].size()<q[f[v]].size())swap(f[k],f[v]); 25 while (!q[f[v]].empty()) 26 qq.push(max(top(q[f[k]]),top(q[f[v]]))); 27 while (!qq.empty())q[f[k]].push(top(qq)); 28 } 29 q[f[k]].push(a[k]); 30 } 31 int main(){ 32 scanf("%d",&n); 33 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 34 for(int i=1;i<=n;i++)f[i]=i; 35 memset(head,-1,sizeof(head)); 36 for(int i=2;i<=n;i++){ 37 scanf("%d",&x); 38 add(x,i); 39 } 40 dfs(1); 41 while (!q[f[1]].empty())ans+=top(q[f[1]]); 42 printf("%lld",ans); 43 }
标签:return scanf while its open amp 时间复杂度 close +=
原文地址:https://www.cnblogs.com/PYWBKTDA/p/11620949.html