zoukankan      html  css  js  c++  java
  • 【cf1247F】F. Tree Factory(构造)

    传送门

    题意:
    给出一颗树。
    现在要构造出一条链,并且对链执行若干次操作:

    • 选择一个结点(v),将结点(v)的父亲指向其爷爷,其余结点不变。

    最终能够得到给出的树。
    输出这条链以及执行的操作,要求操作次数最小。

    思路:
    考虑逆操作,对于一颗树,每次可以选择一个结点,成为其兄弟的儿子(emmm)。
    因为要求操作次数最小,考虑链的性质:长度为(n)也就是深度为(n)
    那么我们会发现,每次选择深度最大的链进行操作,那么总能使得深度加(1)。那么我们就得知最优操作方法了。
    对于一个结点而言,我们肯定先操作最长的那条链、然后次长、...、最后最短。
    那么直接递归执行该操作即可。
    逻辑上还有点细节,详见代码:

    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/9 15:13:04
     */
    #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 pb push_back
    #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...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
    
    int n;
    int p[N];
    vector <int> G[N], sons[N];
    vector <int> ans;
    int deep[N];
    
    void dfs(int u, int fa) {
        for(auto v : G[u]) if(v != fa) {
            dfs(v, u);
            deep[u] = max(deep[u], deep[v] + 1);
            sons[u].push_back(v);
        }
        sort(all(sons[u]), [&](int A, int B) {
            return deep[A] < deep[B];        
        });
    }
    
    void gao(int u, int fa) {
        cout << u << ' ';
        for(int i = 0; i < sz(sons[u]); i++) {
            gao(sons[u][i], u);
            if(i == 0) continue;
            for(int j = 0; j <= deep[sons[u][i - 1]]; j++) {
                ans.push_back(sons[u][i]);
            }   
        }
    }
    
    void run() {
        cin >> n;
        for(int i = 1; i < n; i++) {
            cin >> p[i];
            G[p[i]].push_back(i);   
        }
        dfs(0, 0);
        gao(0, 0);
        cout << '
    ';
        cout << sz(ans) << '
    ';
        for(auto it : ans) cout << it << ' ';
        cout << '
    ';
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    
  • 相关阅读:
    最全的机器学习资源整理
    论文写作技巧
    制造业期刊-ZT
    机器学习中的算法(2)-支持向量机(SVM)基础
    定语从句
    Digital Twin的8种解读!
    详解BOM用途分类及在汽车企业中的应用
    Intellij IDEA运行报Command line is too long解法
    计算机行业各种职业技能树
    invocationCount和invocationTimeOut
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/12450933.html
Copyright © 2011-2022 走看看