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.
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!
題目大意:給你一顆有根樹,然後每個結點都有一個c[i]值,代表以這個 i 結點爲根的子樹有多少個結點的權值小於 i 結點的權值;讓你構造這樣一棵樹,就是構造每個結點的權值,滿足c[i];
構造題,永遠是比較難想的;
可以假設 n 個結點的權值在 1–n 的範圍,從根結點往下構造,先保證根取第 c[i]+1 大的數,然後把剩下來的數分到 i 爲根的各個子樹裏面,dfs一遍就可以,開兩個狀態,一個是結點 i,一個是當前以 i 結點爲根的子樹所包含的權值;
代碼:
#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=10100;
const int M=5000100;
const LL mod=9987;
int n,rt,siz[N],head[N],cnt,c[N];
struct Node{
int to,nex;
}edge[N*2];
void add(int p,int q){
edge[cnt].to=q,edge[cnt].nex=head[p],head[p]=cnt++;
}
void dfs1(int p){
siz[p]=1;
for(int i=head[p];~i;i=edge[i].nex){
dfs1(edge[i].to);
siz[p]+=siz[edge[i].to];
}
}
vector<int>ve;
int ans[N];
void dfs2(int p,vector<int>vc){
ans[p]=vc[c[p]-1];
int pos=0;
for(int i=head[p];~i;i=edge[i].nex){
int q=edge[i].to;
vector<int>vd;
int sum=0;
for(int j=pos;j<vc.size();j++){
if(j==c[p]-1){
pos++;continue;//pos特別注意
}
if(++sum>siz[q]) break;
pos++;
vd.push_back(vc[j]);
}
dfs2(q,vd);
}
}
int main(){
memset(head,-1,sizeof(head));
cin>>n;
for(int i=1;i<=n;i++){
int p;cin>>p>>c[i];c[i]++;
if(p!=0) add(p,i);
else rt=i;
}
dfs1(rt);
for(int i=1;i<=n;i++){
if(c[i]>siz[i]){
printf("NO\n");
return 0;
}
}
for(int i=0;i<n;i++) ve.push_back(i+1);
dfs2(rt,ve);
cout<<"YES"<<endl;
for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
return 0;
}