题意:定义Ci为i点子树中权值比i小的结点个数,给定每个节点的Ci值,要你构造出符合条件的权值序列。
思路:求权值序列可将所有节点的排名序列先构造出来,再根据排名赋值就行。假设i点子树的排名序列已经构造好了,那么把根据i点的Ci值插入到已构造好的序列的相应位置中就是答案,而上述过程可以用dfs实现。例如我们假设当前节点为4,4的Ci值为2,他的子树排名序列为2,5,3。那么根据Ci的意义4就应该插入再5的后面。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e4+1;
int n,a,root,num[maxn],ans[maxn];
vector<int>v[maxn];
vector<int>dfs(int x)
{
vector<int>Rank;
for(int to:v[x])
{
vector<int>temp=dfs(to);
Rank.insert(Rank.end(),temp.begin(),temp.end());
}
if(num[x]>Rank.size()) {
printf("NO\n");
exit(0);
}
Rank.insert(Rank.begin()+num[x],x);
return Rank;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%d %d",&a,&num[i]);
if(a==0) root=i;
else v[a].push_back(i);
}
vector<int>range=dfs(root);
for(int i=0;i<range.size();++i)
ans[range[i]]=i+1;
printf("YES\n");
for(int i=1;i<=n;++i) printf("%d ",ans[i]);
}