题意:给你每个节点的父节点和他子树中有多少比他小的点,让你给这个数赋权满足上述条件
原文链接:https://blog.csdn.net/jziwjxjd/article/details/106177186
首先,构造千万不要想复杂了,尽量往简单的想
我 们 构 造 的 a [ i ] 应 该 互 不 相 同 最 好 , 因 为 相 同 不 好 选 择
比 其 中 一 个 大 就 比 很 多 个 大 , 不 好 确 定 排 名
既 然 如 此 , 我 就 规 定 最 终 a [ i ] 取 [ 1 , n ]
这 样 一 来 根 就 被 唯 一 确 定 是 , a [ r o o t ] = c [ r o o t ] + 1
然 后 d f s 遍 历 下 去 , 每 次 找 到 剩 余 没 有 用 过 的 数 字 中 第 c [ i ] + 1 大 的 数
如 果 某 个 顶 点 的 所 有 子 节 点 数 加 起 来 都 小 于 c [ i ] , 无 解
某 次 为 顶 点 找 第 c [ i ] + 1 大 的 数 没 找 到 , 无 解
#include<iostream>
#include<vector>
using namespace std;
int n;
int tem[2005];
int c[2005];
vector<int> a[2005];
int f = 0;
int Size[2005];
int ans[2005];
int find(int x)
{
int t = 0;
for(int i = 1; i <= n ; i++)
{
if(tem[i] == 0)
continue;
t ++;
if(t == x)
{
tem[i] = 0;
return i;
}
}
return -1;
}
void dfs(int x)
{
Size[x] = 1;
ans[x] = find(c[x] + 1);
if(ans[x] == -1)
f = -1;
for(auto v:a[x])
{
dfs(v);
Size[x] += Size[v];
}
if(Size[x] - 1 < c[x])
{
f = -1;
}
}
int main()
{
scanf("%d",&n);
for(int i = 1; i <= n; i++)
tem[i] = 1;
int root = 0;
for(int i = 1; i <= n; i++)
{
int l;
scanf("%d%d",&l,&c[i]);
a[l].push_back(i);
if(l == 0)
{
root = i;
}
}
dfs(root);
if(f == -1)
printf("NO");
else
{
printf("YES\n");
for(int i = 1; i <= n; i++)
printf("%d ",ans[i]);
}
}