Codeforces Round #612 (Div. 1) B. Numbers on Tree ###K //K

题目链接:https://codeforces.ml/problemset/problem/1286/B

题意:给定一棵有根树 每个节点上有c[i] 代表子树上 有 c[i]个 a[j]<a[i]  问能否找到给每个节点赋值a[i] 使得满足题意

思路: 考虑只用1到n 来编号, 可以证明 从根开始dfs下去 如果当前节点的为c[i] 

那么只需要在1~n的序列后找到第c[i]+1小的值 填上即可, 当然如果c[i]>cnt[u]-1 的时候 肯定是不合法的

其他情况下按照这样编号如果子树正确就可以保证当前节点也是正确的   一定要判子树和c[i]的关系,因为

可能不满足关系的时候也能找到第c[i]+1 小 但这是错的

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=2e3+10;
 4 const int mod=1e9+7;
 5 #define ll long long
 6 #define pi pair<int,int>
 7 #define fi first
 8 #define sc second
 9 #define pb push_back
10 int c[maxn],vis[maxn];
11 vector<int>E[maxn];
12 int sz[maxn],ans[maxn];
13 int f,n;
14 
15 int fk(int x)
16 {
17     int cnt=0;
18     for(int i=1;i<=n;i++)
19     {
20         if(vis[i]) continue;
21         cnt++;
22         if(cnt==x)
23         {
24             vis[i]=1;
25             return i;
26         }
27     }
28     return 0;
29 }
30 
31 void dfs(int u)
32 {
33     sz[u]=1;
34     int x=fk(c[u]+1);
35     if(!x) f=1;
36     ans[u]=x;
37     for(auto &v:E[u])
38     {
39         dfs(v);
40         sz[u]+=sz[v];
41     }
42     if(sz[u]-1<c[u]) f=1;
43 }
44 
45 
46 int main()
47 {
48     ios::sync_with_stdio(0);
49     cin.tie(0);
50     cin>>n;
51     int rt=0;
52     for(int i=1;i<=n;i++)
53     {
54         int x;
55         cin>>x>>c[i];
56         if(!x) rt=i;
57         else E[x].pb(i);
58     }
59     dfs(rt);
60     if(f) cout<<"NO"<<'\n';
61     else
62     {
63         cout<<"YES"<<'\n';
64         for(int i=1;i<=n;i++)
65         {
66             if(i!=1) cout<<" ";
67             cout<<ans[i];
68         }
69     }
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 }
View Code

 

posted @ 2021-02-20 22:39  canwinfor  阅读(45)  评论(0)    收藏  举报