CodeForces 1287 D.Numbers on Tree (dfs)

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;
}
发布了364 篇原创文章 · 获赞 26 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44178736/article/details/103989471