http://codeforces.com/problemset/problem/1287/D
題意:
給出一棵樹,每個點有值(要自己構造),告訴了你每個節點的子樹中有多少個節點的值小於它。
解析:
嘗試用1到n去填空。
從上往下dfs,如果一個節點的小於它的個數爲C,那麼我選擇剩餘數字序列中的第C+1小的數,以此類推。
這樣做直接滿足了C的定義。
代碼:
/*
* Author : Jk_Chen
* Date : 2020-01-09-09.53.23
*/
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define ULL unsigned long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
#define debug(x) cerr<<#x<<" = "<<x<<'\n';
const LL mod=1e9+7;
const int maxn=2009;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/
#define rep_e(i,p,u) for(int i=head[p],u=to[i];i;i=nex[i],u=to[i])
int head[maxn],to[maxn<<1],nex[maxn<<1],now;
void add(int a,int b){
nex[++now]=head[a];head[a]=now;to[now]=b;
}
void init_edge(){
memset(head,0,sizeof head);
now=0;
}
/*_________________________________________________________edge*/
int n;
int c[maxn],siz[maxn];
bool use[maxn];
int ans[maxn];
void dfs0(int p){
siz[p]=1;
rep_e(i,p,u){
dfs0(u);
siz[p]+=siz[u];
}
}
void dfs(int p){
int ct=0;
rep(i,1,n){
if(!use[i])ct++;
if(ct==c[p]+1){
use[i]=1;
ans[p]=i;
break;
}
}
rep_e(i,p,u)dfs(u);
}
int main(){
n=rd;
int rt;
rep(i,1,n){
int fa=rd;c[i]=rd;
if(fa==0)rt=i;
else add(fa,i);
}
dfs0(rt);
rep(p,1,n)if(siz[p]-1<c[p])return 0*printf("NO\n");
printf("YES\n");
dfs(rt);
rep(i,1,n)printf("%d ",ans[i]);
puts("");
}