1287D - Numbers on Tree(構造 想法 樹)

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("");
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章