【cf1286B】B. Numbers on Tree(贪心)

传送门

题意:
给出一颗有根树,每个结点有一个权值\(a_i,1\leq a_i\leq 10^9\);同时,每个结点有一个值\(c_i\),表示其子树中有多少个结点,满足\(a_j<a_i,j\in son_i\)
现在只知道这棵树的\(c_i\),要求构造一种合法的权值序列,满足要求。

思路:

  • \(n\)只有\(2000\),所以可以考虑\(O(n^2)\)的做法。
  • 对于一颗子树,假设其大小为\(sz\),那么我们可以认为树的权值由\(1\)~\(sz\)组成且不重复。那么对于一个结点来说,若其为第\(k\)大,那么就赋与第\(k\)个没有出现的权值。
  • 其余结点同理,递归处理即可。

最后记得检验一下是否合法,简单粗暴的方法再跑次\(dfs\)即可。
代码如下:

/*
 * Author:  heyuhhh
 * Created Time:  2020/1/28 10:59:22
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2000 + 5;
 
int n;
bool chk[N];
vector <int> G[N];
int a[N], c[N];
 
void dfs(int u) {
    int T = 0;
    for(int i = 1; i < N; i++) {
        if(!chk[i]) ++T;
        if(T == c[u] + 1) {
            a[u] = i;
            chk[i] = true;
            break;
        }
    }
    for(auto v : G[u]) dfs(v);
}
 
int dfs2(int u, int x) {
    int res = (a[u] < x);
    for(auto v : G[u]) res += dfs2(v, x);
    return res;
}
 
void run(){
    int rt;
    for(int i = 1; i <= n; i++) {
        int p; cin >> p >> c[i];
        if(p == 0) rt = i;
        else G[p].push_back(i);
    }
    dfs(rt);
    for(int i = 1; i <= n; i++) {
        int x = dfs2(i, a[i]);   
        if(x != c[i]) {
            cout << "NO" << '\n';
            return;    
        }
    }
    cout << "YES" << '\n';
    for(int i = 1; i <= n; i++) cout << a[i] << ' ';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    while(cin >> n) run();
    return 0;
}
posted @ 2020-01-29 21:47  heyuhhh  阅读(292)  评论(0编辑  收藏  举报