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

传送门

题意:
给出一颗有根树,每个结点有一个权值(a_i,1leq a_ileq 10^9);同时,每个结点有一个值(c_i),表示其子树中有多少个结点,满足(a_j<a_i,jin 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 << '
'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '
'; }
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" << '
';
            return;    
        }
    }
    cout << "YES" << '
';
    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;
}
原文地址:https://www.cnblogs.com/heyuhhh/p/12241589.html