D.Numbers on Tree
Evlampiy was gifted a rooted tree. The vertices of the tree are numbered from 1 to n. Each of its vertices also has an integer ai written on it. For each vertex i, Evlampiy calculated ci — the number of vertices j in the subtree of vertex i, such that aj<ai.
Illustration for the second example, the first integer is ai and the integer in parentheses is ci
After the new year, Evlampiy could not remember what his gift was! He remembers the tree and the values of ci, but he completely forgot which integers ai were written on the vertices.
Help him to restore initial integers!
Input
The first line contains an integer n (1≤n≤2000) — the number of vertices in the tree.
The next n lines contain descriptions of vertices: the i-th line contains two integers pi and ci (0≤pi≤n; 0≤ci≤n−1), where pi is the parent of vertex i or 0 if vertex i is root, and ci is the number of vertices j in the subtree of vertex i, such that aj<ai.
It is guaranteed that the values of pi describe a rooted tree with n vertices.
Output
If a solution exists, in the first line print “YES”, and in the second line output n integers ai (1≤ai≤109). If there are several solutions, output any of them. One can prove that if there is a solution, then there is also a solution in which all ai are between 1 and 109.
If there are no solutions, print “NO”.
Examples
Input
3
2 0
0 2
2 0
Output
YES
1 2 1
Input
5
0 1
1 3
2 1
3 0
2 0
Output
YES
2 3 2 1 2
题意:
n个节点的树,每个节点有ai和ci
ai是节点i的值,ci表示i的所有子节点中,有ci个值比它小的
现在给树的形态(每个节点的父节点pre)和每个节点的ci,要求构造出一组ai满足条件
如果能构造出输出YES和ai
否则输出NO
思路:
假设一个节点有k个子节点,ci为c
1.如果c大于k,则肯定NO,因为子节点数量都不够c个
2.如果c小于等于k,把分成两份,一份为c、一份为k-c
当前节点插入到两份中间,节点递增赋值,则前c个小于当前节点值,满足条件
对于每个节点都这样操作即可。
详见代码
code:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=2e3+5;
vector<int>g[maxm];
int c[maxm];
int res[maxm];
int n;
vector<int> dfs(int now){
vector<int>res;//存子节点
for(int x:g[now]){
vector<int>ch=dfs(x);
for(int v:ch){
res.push_back(v);
}
}
if(c[now]>res.size()){//如果没法插入说明不可能
cout<<"NO"<<endl;
exit(0);
}
res.insert(res.begin()+c[now],now);//插到中间
return res;
}
signed main(){
cin>>n;
for(int i=1;i<=n;i++){
int fa;
cin>>fa;
cin>>c[i];
g[fa].push_back(i);
}
vector<int>ans=dfs(0);//0是虚根
for(int i=0;i<(int)ans.size();i++){//节点赋值
res[ans[i]]=i;
}
cout<<"YES"<<endl;
for(int i=1;i<=n;i++){//输出答案
cout<<res[i]<<' ';
}
cout<<endl;
return 0;
}