ZOJ3805Machine(二叉树左右子树变换)

/*
    题意:建立一棵二叉树,左子树和父节点占一个宽度,右子树另外占一个宽度!
          使任意左右子树交换顺序,使得整个树的宽度最小!
    思路:递归交换左右子树 !
       开始写的代码复杂了,其实左右子树不用真的交换,只要返回交换与不交换最小的宽度值就好了,下次不用在查询了!
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 10005
using namespace std;

int tree[N][2];
int link[N];
int n;

int dfs(int cur){
   if(cur==0) return 0;
   int aR=1+dfs(tree[cur][1]);//右子树的宽度
   int aL=dfs(tree[cur][0]);//左子树的宽度
   return min(max(aR-1, aL+1), max(aR, aL));//aR-1是右子树变成左子树后的宽度,aL是左子树变成右子树的宽度
}

int main(){
   while(scanf("%d", &n)!=EOF){
          memset(tree, 0, sizeof(tree));
          memset(link, 0, sizeof(link));
       for(int i=1; i<n; ++i){
          int u;
          scanf("%d", &u);
          if(link[u]==0){
              link[u]=1;
              tree[u][0]=i+1;
          }
          else {
              tree[u][1]=i+1;
          }
       }
       printf("%d\n", dfs(1));
   }
   return 0;
}
//这个就是写复杂了,但是很庆幸的过了!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 10005
using namespace std;

int tree[N][2];
int link[N];
int n, wide;

int dfs(int cur){
   if(cur==0) return 0;
   int aR=1+dfs(tree[cur][1]);
   int aL=dfs(tree[cur][0]);
   return max(aL, aR);
}

void updateT(int cur){
    if(cur==0) return;
    updateT(tree[cur][0]);
    updateT(tree[cur][1]);
    int aL, aR;
    aL=dfs(tree[cur][0]);
    aR=1+dfs(tree[cur][1]);
    if(cur==1)  wide=min(max(aR-1, aL+1), max(aR, aL));
    if(aR-aL>1){
        int tmp=tree[cur][1];
        tree[cur][1]=tree[cur][0];
        tree[cur][0]=tmp;
    }
}

int main(){
   while(scanf("%d", &n)!=EOF){
          memset(tree, 0, sizeof(tree));
          memset(link, 0, sizeof(link));
       for(int i=1; i<n; ++i){
          int u;
          scanf("%d", &u);
          if(link[u]==0){
              link[u]=1;
              tree[u][0]=i+1;
          }
          else {
              tree[u][1]=i+1;
          }
       }
       updateT(1);
       printf("%d\n", wide);
   }
   return 0;
}
时间: 2024-10-01 02:19:29

ZOJ3805Machine(二叉树左右子树变换)的相关文章

如何判断一个树是不是另外一个二叉树的子树呢?

问题描述 如何判断一个树是不是另外一个二叉树的子树呢? 请教大神们一个数据结构的问题,才学,琢磨很久没想出来 解决方案 //判断root2是不是root1开头的子结构 boolIsSubTree(BiTreeNode *root1BiTreeNode *root2) { //先判断root2 if(root2==NULL) return true; if(root1==NULL) return false; if(root1->data!=root2->data) return false;

数据结构教程 第二十一课 树、二叉树定义及术语

教学目的: 掌握树.二叉树的基本概念和术语,二叉树的性质 教学重点: 二叉树的定义.二叉树的性质 教学难点: 二叉树的性质 授课内容: 一.树的定义: 树是n(n>=0)个结点的有限集.在任意一棵非空树中: (1)有且仅有一个特定的称为根的结点: (2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1,T2,...Tm,其中每一个集合本身又是一棵树,并且称为根的子树. 二.树的基本概念: 树的结点包含一个数据元素及若干指向其子树的分支. 结点拥有的子树数称为结点的度. 度为0

[算法系列之二]二叉树各种遍历

[简介] 树形结构是一类重要的非线性数据结构,其中以树和二叉树最为常用. 二叉树是每个结点最多有两个子树的有序树.通常子树的根被称作"左子树"(left subtree)和"右子树"(right subtree).二叉树常被用作二叉查找树和二叉堆或是二叉排序树.二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒.二叉树的第i层至多有2的 i -1次方个结点:深度为k的二叉树至多有2^(k) -1个结点:对任何一棵二叉树T,

数据结构之---二叉树C实现

学过数据结构的都知道树,那么什么是树? 树(tree)是包含n(n>0)个结点的有穷集,其中: (1)每个元素称为结点(node): (2)有一个特定的结点被称为根结点或树根(root). (3)除根结点之外的其余数据元素被分为m(m≥0)个互不相交的集合T1,T2,--Tm-1,其中每一个集合Ti(1<=i<=m)本身也是一棵树,被称作原树的子树(subtree). 树也可以这样定义:树是由根结点和若干颗子树构成的.树是由一个集合以及在该集合上定义的一种关系构成的.集合中的元素称为树的

求助!用二叉树构建倒排索引文件出现错误

问题描述 求助!用二叉树构建倒排索引文件出现错误 目录text下共十个编号为P0到P9的txt文件,分别写有一个字母a,b,c... 用二叉树的构建倒排索引输出在Index.txt里, 应该按字母顺序输出字母出现的频率和文档id,即 "a 1 0 b 1 1 c 1 2 ... j 1 9" 运行结果却是Index.txt里只有"c 1 0 "一行... 各位大神帮忙查一下哪里出了问题... 代码如下: #include #include #include #def

第十章 基本数据结构——二叉树

可以参考:http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html 摘要 书中第10章10.4小节介绍了有根树,简单介绍了二叉树和分支数目无限制的有根树的存储结构,而没有关于二叉树的遍历过程.为此对二叉树做个简单的总结,介绍一下二叉树基本概念.性质.二叉树的存储结构和遍历过程,主要包括先根遍历.中根遍历.后根遍历和层次遍历. 1.二叉树的定义 二叉树(Binary Tree)是一种特殊的树型结构,每个节点至多有两棵子树,

jquery mobile中怎么将input和button放在同一行

问题描述 jquery mobile中怎么将input和button放在同一行 jquery mobile中怎么将input和button放在同一行 解决方案 <div class="ui-grid-a"> <div class="ui-block-a"> <input name="telcx" id="telcx" type="tel" value=""

程序员面试资源大收集(转)

资源一:<crack the code interview>--谷歌资深技术面试官经典之作 本书的中文目录如下,大部分内容由Hawstein君原创翻译,部分缺失的由快课网Jay13补充. 1.1 判断一个字符串中的字符是否唯一 1.2 字符串翻转 1.3 去除字符串中重复字符 1.8 利用已知函数判断字符串是否为另一字符串的子串 2.1 从链表中移除重复结点 2.2 实现一个算法从一个单链表中返回倒数第n个元素 2.3 给定链表中间某结点指针,删除链表中该结点 2.4 求由两个链表结点组成的数

c语言-C语言,程序结构 程序不能正常运行

问题描述 C语言,程序结构 程序不能正常运行 #include #include #define num 100 #define OK 1 typedef int Status; typedef char DataType; typedef struct node { DataType data; struct node *lchild,*rchild; }BinTNode,*BinTree; int found; BinTNode *p; /*****************建立二叉树****