LG12652
注意到点的权值是从叶子往根节点 \(1\) 传递的,一个点的点权向父节点传递后,会从子节点中选一个最小的权值。由此,我们可以使用优先队列维护当前 \(1\) 周围的权值。当点 \(u\) 的权值最小时,把 \(u\) 的所有子节点 \(v\) 加入优先队列,这样能保证 \(u\) 的权值能够更新为子节点权值最小值(再次被选时也能够用其它子节点继续更新)。时间复杂度 \(O(n\log n)\)。
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#define N 300010
using namespace std;
int n,a[N];
vector<int> G[N];
priority_queue<int,vector<pair<int,int> >,greater<pair<int,int> > > q;
int main(){
int u;
cin>>n;
for(int i=2;i<=n;i++){
cin>>u;
G[u].push_back(i);
}
for(int i=1;i<=n;i++)
cin>>a[i];
q.push(make_pair(a[1],1));
while(!q.empty()){
u=q.top().second;
cout<<q.top().first<<'\n';
q.pop();
for(auto v:G[u])
q.push(make_pair(a[v],v));
}
return 0;
}

浙公网安备 33010602011771号