D. Numbers on Tree

题目链接:https://codeforces.com/contest/1287/problem/D

 

题意:

 n个节点的树,每个节点有ai和ci ai是节点i的值,ci表示i的所有子节点中,有ci个值比它小的 现在给树的形态(每个节点的父节点pre)和每个节点的ci,要求构造出一组ai满足条件 如果能构造出输出YES和ai 否则输出NO

 

想法:

我们不难知道当前节点 u 的点权只对它的子树中的节点的点权有影响,所以我们应该从上自下去遍历整棵树。

我们从顶点开始放,没放的数字我们是一定知道的(因为只有1-n)。所以放的时候相当于在没放的数字中找到第c[i]+1大的数字,放上去。即可满足条件,继续向下递归。

 

#include <algorithm>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <math.h>
#include <cstdio>
#include <iomanip>
#include <time.h>
#include <bitset>
#include <cmath>
#include <sstream>
#include <iostream>
#include <cstring>

#define LL long long
#define ls nod<<1
#define rs (nod<<1)+1
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define INF 0x3f3f3f3f

const double eps = 1e-10;
const int maxn = 2000 + 10;
const LL mod = 1e9 + 7;

int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
using namespace std;

struct edge{
    int v,nxt;
}e[maxn<<1];

int cnt;
int head[maxn];
int c[maxn],siz[maxn],p[maxn];
int vis[maxn];
int tot,n;

inline void add_edge(int u,int v) {
    e[++cnt].v = v;
    e[cnt].nxt = head[u];
    head[u] = cnt;
}

inline void get_siz(int u) {
    siz[u] = 1;
    for (int i = head[u];~i;i = e[i].nxt) {
        int v = e[i].v;
        get_siz(v);
        siz[u] += siz[v];
    }
}

inline void dfs(int u) {
    if (c[u] > siz[u]-1) {
        cout << "NO" << endl;
        exit(0);
    }
    int xx = 0;
    for (int i = 1;i <= n;i++) {
        if (!vis[i])
            xx++;
        if (xx == c[u]+1) {
            p[u] = i;
            vis[i] = 1;
            break;
        }
    }
    for (int i = head[u];~i;i = e[i].nxt)
        dfs(e[i].v);
}

int main() {
    scanf("%d",&n);
    int root;
    memset(head,-1, sizeof(head));
    cnt = 0;
    for (int i = 1;i <= n;i++) {
        int f;
        scanf("%d%d",&f,&c[i]);
        if (f == 0)
            root = i;
        else
            add_edge(f,i);
    }
    get_siz(root);
    tot = 1;
    dfs(root);
    printf("YES\n");
    for (int i = 1;i <= n;i++)
        printf("%d ",p[i]);
    printf("\n");
    return 0;
}

 

posted @ 2020-03-09 21:24  _Ackerman  阅读(190)  评论(0编辑  收藏  举报