首页 > 其他分享 >洛谷 P5018 对称二叉树

洛谷 P5018 对称二叉树

时间:2024-03-14 22:30:46浏览次数:17  
标签:return int 洛谷 bt 二叉树 P5018 节点 now2

题目背景

NOIP2018 普及组 T4

题目描述

一棵有点权的有根树如果满足以下条件,则被轩轩称为对称二叉树:

  1. 二叉树;
  2. 将这棵树所有节点的左右子树交换,新树和原树对应位置的结构相同且点权相等。

下图中节点内的数字为权值,节点外的 idid 表示节点编号。

现在给出一棵二叉树,希望你找出它的一棵子树,该子树为对称二叉树,且节点数最多。请输出这棵子树的节点数。

注意:只有树根的树也是对称二叉树。本题中约定,以节点 TT 为子树根的一棵“子 树”指的是:节点TT 和它的全部后代节点构成的二叉树。

输入格式

第一行一个正整数 nn,表示给定的树的节点的数目,规定节点编号 1 \sim n1∼n,其中节点 11 是树根。

第二行 nn 个正整数,用一个空格分隔,第 ii 个正整数 v_ivi​ 代表节点 ii 的权值。

接下来 nn 行,每行两个正整数 l_i, r_ili​,ri​,分别表示节点 ii 的左右孩子的编号。如果不存在左 / 右孩子,则以 -1−1 表示。两个数之间用一个空格隔开。

输出格式

输出文件共一行,包含一个整数,表示给定的树的最大对称二叉子树的节点数。

输入输出样例

输入 #1复制

2 
1 3 
2 -1 
-1 -1 

输出 #1复制

1

输入 #2复制

10 
2 2 5 5 5 5 4 4 2 3 
9 10 
-1 -1 
-1 -1 
-1 -1 
-1 -1 
-1 2 
3 4 
5 6 
-1 -1 
7 8

输出 #2复制

3

说明/提示

样例 1 解释


最大的对称二叉子树为以节点 22 为树根的子树,节点数为 11。

样例 2 解释

最大的对称二叉子树为以节点 77 为树根的子树,节点数为 33。

数据规模与约定

本题约定:

层次:节点的层次从根开始定义起,根为第一层,根的孩子为第二层。树中任一节 点的层次等于其父亲节点的层次加 11。

树的深度:树中节点的最大层次称为树的深度。

满二叉树:设二叉树的深度为 hh,且二叉树有 2^h-12h−1 个节点,这就是满二叉树。

完全二叉树:设二叉树的深度为 hh,除第 hh 层外,其它各层的结点数都达到最大 个数,第 hh 层所有的结点都连续集中在最左边,这就是完全二叉树。

本题注意:

空数也是对称二叉树。

在判断数是否是对称二叉树时,需要定义两个树,分别判断两棵树是否为空树。

如果两棵树都为空数,直接return true;

如果两棵树一棵为空树,另一棵为非空树,肯定不是对称的,直接return false;

如果两个条件都满足,判断树的权值是否相等,如果不等,直接return false;

继续判断它们的子树是否满足条件。

使用一个函数计算子树的值。特别注意:要加上一(根节点);

判断是否对称代码如下:

bool same(int now1,int now2){
	if(now1==-1 && now2==-1){
		return true;
	}
	if(now1==-1 || now2==-1){
		return false;
	}
	if(bt[now1].val!=bt[now2].val){
		return false;
	}
	return same(bt[now1].left,bt[now2].right)	&&	same(bt[now1].right,bt[now2].left);
} 

计算结点个数代码如下:

int cum(int now){
	if(now==-1){
		return 0;
	}
	return 1+cum(bt[now].left)+cum(bt[now].right);
}

完整代码如下:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+2;
struct node{
	int left,right;		//left表示左子树,right表示右子树;
	int val;		//val表示每个结点的权值; 
} bt[N];
bool same(int now1,int now2){
	if(now1==-1 && now2==-1){
		return true;
	}
	if(now1==-1 || now2==-1){
		return false;
	}
	if(bt[now1].val!=bt[now2].val){
		return false;
	}
	return same(bt[now1].left,bt[now2].right)	&&	same(bt[now1].right,bt[now2].left);
} 
int cum(int now){
	if(now==-1){
		return 0;
	}
	return 1+cum(bt[now].left)+cum(bt[now].right);
}
int main(){
	int n,ans=0;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&bt[i].val);
	}
	for(int i=1;i<=n;i++){
		scanf("%d %d",&bt[i].left,&bt[i].right);
	} 
	for(int i=1;i<=n;i++){
		if(same(i,i)){
			ans=max(ans,cum(i));
		}
	}
	cout<<ans<<endl;
	return 0;
}

标签:return,int,洛谷,bt,二叉树,P5018,节点,now2
From: https://blog.csdn.net/xiebohang/article/details/136722423

相关文章

  • 洛谷 B3625 迷宫寻路
    本道题需要注意:如果孩子的起始位置就是‘#’,那孩子就无路可走,出不来了。所以需要特判一下,代码如下:(这是废话,不需要特判,注意题目要求)if(ch[1][1]=='#'){ printf("No\n"); }注意边界条件:if(nx<1||nx>n||ny<1||ny>m){ continue; } if(vis[nx][ny]==1){ cont......
  • P8681 [蓝桥杯 2019 省 AB] 完全二叉树的权值
    题目描述给定一棵包含N 个节点的完全二叉树,树上每个节点都有一个权值,按从上到下、从左到右的顺序依次是​,如下图所示: 现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的节点权值之和最大?如果有多个深度的权值和同为最大,请你输出其中最小的深度。注:根的深度是 1......
  • 二叉树
    节点类定义classTreeNode{privateStringvalue;privateTreeNodeleft;privateTreeNoderight;publicTreeNode(Stringvalue){this.value=value;this.left=null;this.right=null;}publicvoidsetLeft(Tr......
  • 第六章二叉树——二叉树的最大深度
    吾日三省吾身还记得的梦想吗正在努力实现它吗可以坚持下去吗目录吾日三省吾身力扣题号:104.二叉树的最大深度-力扣(LeetCode)题目描述:思路解法一:递归实现思路代码逻辑解释注意事项代码实现内存优化总结(╯°□°)╯︵┻━┻(⌐■_■)(¬‿¬)(´・ω・`)(͡°͜......
  • 236. 二叉树的最近公共祖先c
    /***Definitionforabinarytreenode.*structTreeNode{*intval;*structTreeNode*left;*structTreeNode*right;*};*/structTreeNode*lowestCommonAncestor(structTreeNode*root,structTreeNode*p,structTreeNode*q){......
  • 洛谷 P3596 [POI2015] MOD 题解
    题意简述给定一棵树,求断掉一条边再连上一条边所得的新树直径最小值和最大值,以及相应方案(你可以不进行任何操作,即断掉并连上同一条边)。题目分析假设我们枚举断掉某一条边,得到了两棵树,并且知道它们的直径分别为\(d_0,d_1\),那么如何连接一条边让新树的直径最大/最小呢?最大:显......
  • 洛谷 P3261 [JLOI2015] 城池攻占 题解
    题目分析其他人要么倍增,要么左偏树,那我就来讲讲朴实无华的dfs序加上线段树的做法。首先发现题目中明确指出了作乘法的时候一定是乘上一个大于零的数,这是为什么呢?首先把可以占领当前城池的战斗力的不等式列出来:\[h_j\le\left\{\begin{array}{c}s_i\timesv_j&&{a_j=......
  • leedcode-完全二叉树的节点个数
    自己写的,使用广度优先BFS,迭代:classSolution:defcountNodes(self,root:Optional[TreeNode])->int:#如果根节点为空,则树中节点数为0ifnotroot:return0#初始化队列,并将根节点放入队列中queue=[root]......
  • 洛谷题单指南-二叉树-P5076 【深基16.例7】普通二叉树(简化版)
    原题链接:https://www.luogu.com.cn/problem/P5076题意解读:此题本质上是要实现一个二叉搜索树的功能。解题思路:从数据规模10^4来看,只要复杂度在n^2范围内基本上是可以通过的,下面给出两种做法:1、有序数组法对应5个操作的实现逻辑如下:操作一:查x的排名。直接通过二分查找>=x的第......
  • C语言:洛谷数组题目(2)(冰雹猜想,校门外的树,旗鼓相当的对手)
    目录1.前言2.三则题目1.冰雹猜想1.题目描述2.输入格式3.输出格式4.题解2.校门外的树1.题目描述2.输入格式3.输出格式4.题解3.旗鼓相当的对手1.题目描述2.输入格式3.输出格式4.题解3.小结1.前言今天小蒟蒻继续为大家分享洛谷数组题单题解,一共三道题,希望大......