zoukankan      html  css  js  c++  java
  • 哈尔滨理工大学第七届程序设计竞赛决赛(网络赛-高年级组)H

    题目描述

    给一个有根二叉树,可以无限次的交换任意节点的左右子树,问最少交换多少次使得该树的中序遍历的字典序最小?

    输入描述:

    每个测试点有仅有一组数据
    每组测试数据的一行有两个整数N,M,代表有N个节点,M为根节点。
    接下来N行,每行两个整数ai,bi.ai表示第i个节点的左儿子,bi表示第i个节点的右儿子.

    N∈[1,5×105]
    ai,bi,M∈[1,N] 当ai,bi为0时 表示空节点.

    输出描述:

    输出两行
    第一行 为最小交换次数.
    第二行 为字典序最小的中序遍历.
    示例1

    输入

    7 4
    0 0
    1 3
    0 0
    2 5
    6 7
    0 0
    0 0

    输出

    0
    1 2 3 4 6 5 7

    题解

    树形$dp$。

    这题保证了每个数字都是不一样的,所以难度极小。记录$dp[i]$表示以$i$为根的子树中序遍历第一个数字的最小值,从下往上推一发就能知道哪些节点需要交换了。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 5e5 + 10;
    int L[maxn], R[maxn];
    int f[maxn], p[maxn];
    int n, m;
    int u[maxn], sz;
    
    void dfs(int x) {
      if(L[x] == 0 && R[x] == 0) {
        p[x] = x;
        return;
      }
      if(L[x]) dfs(L[x]);
      if(R[x]) dfs(R[x]);
      if(L[x] != 0 && R[x] != 0) {
        if(p[L[x]] > p[R[x]]) {
          f[x] = 1;
          p[x] = p[R[x]];
        } else {
          p[x] = p[L[x]];
        }
      } else if(L[x] == 0) {
        if(p[R[x]] < x) {
          f[x] = 1;
          p[x] = p[R[x]];
        } else {
          p[x] = x;
        }
      } else {
        if(p[L[x]] > x) {
          f[x] = 1;
          p[x] = x;
        } else {
          p[x] = p[L[x]];
        }
      }
    }
    
    void work(int x) {
      if(L[x]) work(L[x]);
      u[sz ++] = x;
      if(R[x]) work(R[x]);
    }
    
    int main() {
      while(~scanf("%d%d", &n, &m)) {
        for(int i = 1; i <= n; i ++) {
          scanf("%d%d", &L[i], &R[i]);
          f[i] = 0;
          p[i] = 0;
        }
        dfs(m);
        int ans = 0;
        for(int i = 1; i <= n; i ++) {
          ans = ans + f[i];
          if(f[i]) swap(L[i], R[i]);
        }
        printf("%d
    ", ans);
        sz = 0;
        work(m);
        for(int i = 0; i < n; i ++) {
          printf("%d", u[i]);
          if(i < n - 1) printf(" ");
          else printf("
    ");
        }
      }
      return 0;
    }
    

      

  • 相关阅读:
    UVA 11488 Hyper Prefix Sets (字典树)
    UVALive 3295 Counting Triangles
    POJ 2752 Seek the Name, Seek the Fame (KMP)
    UVA 11584 Partitioning by Palindromes (字符串区间dp)
    UVA 11100 The Trip, 2007 (贪心)
    JXNU暑期选拔赛
    计蒜客---N的-2进制表示
    计蒜客---线段的总长
    计蒜客---最大质因数
    JustOj 2009: P1016 (dp)
  • 原文地址:https://www.cnblogs.com/zufezzt/p/8065097.html
Copyright © 2011-2022 走看看