• 【bzoj1149】 [CTSC2007]风玲Mobiles


    题目意为:给一颗二叉树,每一次操作可以交换该子树的左右两颗子树,要将该树变为完全二叉树,求最小操作次数。
    从根开始进行一遍DFS。记录每棵子树的大小size,如果左子树的size小于右子树的size那么答案+1。实际上并不需要真的将两颗子树交换。接下来就是处理无解的情况了。
    我们进行分类讨论。
      1. 由题意得树的最大深度max_deep-min_deep<=1。我们可以在DFS的过程中记录deep来实现。

      2. 判断两颗子树交换后左子树的右儿子size小于右子树左儿子size的情况。通过观察我们发现,当max_deep==min_deep时,size_left==2^n。size_right==2^k。那么当两颗子树都不满足这个条件时即为无解

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 using namespace std;
     8  
     9 #define N 200010
    10  
    11 struct Node
    12 {
    13     int l,r,deep,data;
    14 }tr[N<<1];
    15  
    16 int n,m;
    17 int l,r,depl,depr;
    18 int ans;
    19  
    20 int a[N];
    21  
    22 void dfs(int k)
    23 {
    24     if (ans==-1)
    25         return ; 
    26     if (tr[k].l!=-1)
    27         dfs(tr[k].l);
    28     if (tr[k].r!=-1)
    29         dfs(tr[k].r);
    30     if (ans==-1)
    31         return ;
    32     if (tr[k].l!=-1)
    33         l=tr[tr[k].l].data;
    34     else
    35         l=1;
    36     if (tr[k].r!=-1)
    37         r=tr[tr[k].r].data;
    38     else
    39         r=1;
    40     if (l==1)
    41         depl=1;
    42     else
    43         depl=tr[tr[k].l].deep;
    44     if (r==1)
    45         depr=1;
    46     else
    47         depr=tr[tr[k].r].deep;
    48     if ((abs(depl-depr)>1) || (!a[l] && !a[r] && l!=1 && r!=1))
    49     {
    50         ans=-1;
    51         return ;
    52     }
    53     else if (l<r)
    54         ans++;
    55     tr[k].deep=max(depl,depr)+1;
    56     tr[k].data=l+r;
    57 }
    58  
    59 int main()
    60 {
    61     scanf("%d",&n);
    62     for (int i=1;i<=200000;i<<=1)
    63         a[i]=1;
    64     for (int i=1;i<=n;i++)
    65         scanf("%d%d",&tr[i].l,&tr[i].r);
    66     dfs(1);
    67     printf("%d",ans);
    68     return 0;
    69 }
  • 相关阅读:
    linux配置ssh互信
    查看LINUX进程内存占用情况
    RSync实现文件备份同步详解
    rsync同步完整配置
    Linux下利用rsync实现多服务器文件同步
    Linux下的split 命令(将一个大文件根据行数平均分成若干个小文件)
    Linux大文件分割split和合并cat使用方法
    Linux计划任务入门详解
    一步一步理解最大熵模型
    一步一步理解word2Vec
  • 原文地址:https://www.cnblogs.com/yangjiyuan/p/5492091.html
Copyright © 2020-2023  润新知