[NOIP普及组2018-T4]对称二叉树-题解报告

我的洛谷博客

题目大意

给出一个二叉树,判断给定的树的最大对称二叉子树的节点数

划重点部分

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

2.以节点T为子树根的一棵“子树”指的是:节点T 和它的全部后代节点构成的二叉树。

题解

当时看到这题第一反应:把这颗树直接交换,看每个点是否相等,然后,我:好像好难好麻烦,去写T3吧(T3不是更难吗???)

首先我们可以枚举答案子树的根,也就是O(n),然后在n中满足条件的所有根中,找到对称数最多的树。

判断直接去递归,没有子节点的设左右子节点为-1(其实就是题目输入)。

因为二叉树是对称的,所以只要判断每组对称点,在两个点都不是-1的情况下,只要判断两个对称点是否权值相等。如果每组对称点都相等,那么以这个节点为跟的子树就为对称二叉树。

具体操作如下:


先枚举根节点,首先根节点为1

如图,初始化cnt=1(根节点),传入递归节点<2>,<3>,即f(2,3)

因为 <2>与<3>节点权值相等,所以cnt+=2,即cnt=3

往下递归,<2>的子节点和<3>的子节点中的对应点,即f(4,7)与f(5,6)。

f(4,7)中,节点<4>与<7>权值相等,对称,cnt+=2,cnt=5

继续往下递归,发现2组对称点都为2个-1,故结构相等。

f(5,6)中,节点<5>与<6>权值相等,对称,cnt+=2,cnt=7

继续往下递归,发现2组对称点都为2个-1,故结构相等。

所以,根节点为1时,答案为7.

再去判断根为2,3,4,5,6,7,发现答案都没有根为1时大,所以此二叉树最大对称值为7

代码

#include<iostream>
#include<cstdio>
using namespace std;
struct tree{
    int left,right,data;
}a[1000001],b[1000001]; 
int n,ans;
bool f;
int w(int x,int y)
{    if(x==-1&&y==-1)return 0;
    if((x==-1||y==-1)||(a[x].data!=a[y].data))
    {    f=1;
        return 0;
    }
    return w(a[x].left,a[y].right)+w(a[x].right,a[y].left)+2;
}
int main()
{    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i].data);
    for(int i=1;i<=n;i++)
    {    int x,y;
        scanf("%d%d",&x,&y);
        a[i].left=x;
        a[i].right=y;
    }
    for(int i=1;i<=n;i++)
    {    int x=w(a[i].left,a[i].right)+1;
        if(x>ans&&!f)ans=x;
        f=0;
    }
    printf("%d",ans);
    return 0;
}

by N_mustard
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hbqjzx

你的鼓励将是我分享的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值