zoukankan      html  css  js  c++  java
  • LOJ2324. 「清华集训 2017」小 Y 和二叉树【贪心】【DP】【思维】【好】

    LINK


    思路

    首先贪新的思路是处理出以一个节点为根所有儿子的子树中中序遍历起始节点最小是多少
    然后这个可以两次dfs来DP处理
    然后就试图确定中序遍历的第一个节点
    一定是siz<=2的编号最小的节点
    这样肯定是最小的
    那么来考虑从这个节点向右上和右下方扩展整棵树
    一定是不能向左上或左下,不然就不优秀了
    如果当前节点右除了左下有两个儿子,那么最小值小的放在右下,递归处理,大的放在右上,递归处理
    如果只有一个儿子,就比较儿子和当前节点的大小并递归处理就可以了

    好题啊


    //Author: dream_maker
    #include<bits/stdc++.h>
    using namespace std;
    //----------------------------------------------
    //typename
    typedef long long ll;
    typedef pair<int, int> pi;
    //convenient for
    #define fu(a, b, c) for (int a = b; a <= c; ++a)
    #define fd(a, b, c) for (int a = b; a >= c; --a)
    #define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
    //inf of different typename
    const int INF_of_int = 1e9;
    const ll INF_of_ll = 1e18;
    //fast read and write
    template <typename T>
    void Read(T &x) {
      bool w = 1;x = 0;
      char c = getchar();
      while (!isdigit(c) && c != '-') c = getchar();
      if (c == '-') w = 0, c = getchar();
      while (isdigit(c)) {
        x = (x<<1) + (x<<3) + c -'0';
        c = getchar();
      }
      if (!w) x = -x;
    }
    template <typename T>
    void Write(T x) {
      if (x < 0) {
        putchar('-');
        x = -x; 
      }
      if (x > 9) Write(x / 10);
      putchar(x % 10 + '0');
    }
    //----------------------------------------------
    const int N = 1e6 + 10;
    int n, siz[N];
    int ans[N], now[N], cnt;
    int f[N][4], ch[N][4], anc[N];
    int dfs1(int u, int fa) {
      int res = INF_of_int;
      fu(i, 1, siz[u]) {
        int v = ch[u][i];
        if (v == fa) {
          anc[u] = i;
          continue;
        }
        f[u][i] = dfs1(v, u);
        res = min(res, f[u][i]);
      }
      if (siz[u] == 1 && fa) return u;
      if (siz[u] == 2 && fa) return min(u, res);
      return res;
    }
    void dfs2(int u) {
      int minv = INF_of_int, fa = ch[u][anc[u]];
      fu(i, 1, siz[fa]) {
        int v = ch[fa][i]; 
        if (v == u) continue;
        minv = min(minv, f[fa][i]);
      }
      if (siz[fa] <= 2) minv = min(minv, fa);
      f[u][anc[u]] = minv;
      fu(i, 1, siz[u]) {
        int v = ch[u][i];
        if (v == fa) continue;
        dfs2(v);
      }
    }
    void getnow(int u, int fa) {
      pi tmp[4];
      int ind = 0;
      fu(i, 1, siz[u]) {
        int v = ch[u][i];
        if (v == fa) continue;
        tmp[++ind] = pi(f[u][i], i);
      }
      if (!ind) {
        ans[++cnt] = u;
        return;
      }
      sort(tmp + 1, tmp + ind + 1);
      if (ind == 1) {
        if (f[u][tmp[1].second] < u) {
          getnow(ch[u][tmp[1].second], u);
          ans[++cnt] = u;
        } else {
          ans[++cnt] = u;
          getnow(ch[u][tmp[1].second], u);
        }
      } else {
        getnow(ch[u][tmp[1].second], u);
        ans[++cnt] = u;
        getnow(ch[u][tmp[2].second], u);
      }
    }
    void solve(int u, int fro) {
      ans[++cnt] = u;
      pi tmp[4];
      int ind = 0;
      fu(i, 1, siz[u]) {
        int v = ch[u][i];
        if (v == fro) continue;
        tmp[++ind] = pi(f[u][i], i);
      }
      if (!ind) return;
      sort(tmp + 1, tmp + ind + 1);
      if (ind == 1) {
        int nxt = ch[u][tmp[1].second];
        int minv = INF_of_int;
        fu(i, 1, siz[nxt])
          if (ch[nxt][i] != u) minv = min(minv, f[nxt][i]);
        if (minv < nxt) {
          getnow(nxt, u);
        } else {
          solve(nxt, u);
        }
      } else {
        getnow(ch[u][tmp[1].second], u);
        solve(ch[u][tmp[2].second], u);
      } 
    }
    int main() {
      Read(n);
      fu(i, 1, n) {
        Read(siz[i]);
        fu(j, 1, siz[i]) Read(ch[i][j]);
      }
      dfs1(1, 0);
      dfs2(1);
      fu(i, 1, n) ans[i] = n;
      int pos = 0;
      fu(i, 1, n)
        if (siz[i] <= 2) {pos = i; break;}
      solve(pos, 0);
      fu(i, 1, n) {
        Write(ans[i]);
        putchar(' ');
      }
      return 0;
    }
    
  • 相关阅读:
    framework7 底部弹层popup js关闭方法
    div动画旋转效果
    面试题3
    面试题2
    CORS跨域请求[简单请求与复杂请求]
    面试题1
    nginx
    Pycharm配置支持vue语法
    Ajax在jQuery中的应用---加载异步数据
    jQuery开发入门
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9735729.html
Copyright © 2011-2022 走看看