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;
}
posted @ 2025-09-12 08:09  FormulaOne  阅读(15)  评论(0)    收藏  举报