zoukankan      html  css  js  c++  java
  • 【cf1283F】F. DIY Garland(构造)

    传送门

    题意:
    现有一颗有根树,每个结点(i)有权值(2^i),每条边有权值为这条边连接的深度较大的结点的子树权值和。
    但现在并不知道这颗树的形态。
    现在只会给出以下信息:按照边的权值从大到小进行排序,然后依次给出每条边的父亲结点。
    现在要确定这颗树的形态。

    思路:
    假设每次给出的父亲结点为(p_i),那么显然(p_1)为根节点。
    注意,因为每个结点的权值为(2^i),那么可以知道我们会依次找(2^n,2^{n-1},cdots,2^1)这些结点的位置。根据这一点,可以直接分情况讨论:

    • 记录一个变量(now)为目前需要找的结点。
    • (p_i)已存在,说明要新产生一颗子树,并且(now)结点已找到,为(p_{i-1})的儿子;
    • (p_i)不存在,那么就是继续在寻找(now)结点,继续往当前子树深入即可。

    注意用一个数组来标记结点是否找到。
    细节见代码:

    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/1 15:51:31
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #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 = 2e5 + 5;
    
    int n;
    int a[N];
    bool chk[N];
    
    void run(){ 
        vector <pii> edges;
        for(int i = 1; i < n; i++) cin >> a[i];
        int rt = a[1];
        chk[rt] = true;
        cout << rt << '
    ';
        int now = n;
        while(chk[now]) --now;
        for(int i = 2; i < n; i++) {
            if(!chk[a[i]]) {
                edges.push_back(MP(rt, a[i]));
                rt = a[i];
                chk[rt] = true;
            } else {
                edges.push_back(MP(rt, now));
                chk[now] = true;
                rt = a[i];
            }
            while(chk[now]) --now;
        }
        assert(now > 0);
        edges.push_back(MP(rt, now));
        for(auto it : edges) {
            cout << it.fi << ' ' << it.se << '
    ';   
        }
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        while(cin >> n) run();
        return 0;
    }
    
  • 相关阅读:
    DAY21
    DAY20
    DAY19
    @Autowired注解和静态方法
    PageHelper.startPage和new PageInfo(list)的一些探索和思考
    escape()、encodeURI()、encodeURIComponent()区别详解
    每日日报29
    1dialog 表单最基本的封装
    mongoose
    数组
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/12450806.html
Copyright © 2011-2022 走看看