[NOIP2018-普及组] 对称二叉树 - 题解

  • 题目大意

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

    二叉树;
    1. 将这棵树所有节点的左右子树交换,新树和原树对应位置的结构相同且点权相等。
    2. 下图中节点内的数字为权值,节点外的 idid 表示节点编号。

    [NOIP2018-普及组] 对称二叉树 - 题解

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

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

  • 划重点部分

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

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

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

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

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

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

  • 具体操作如下:

    [NOIP2018-普及组] 对称二叉树 - 题解

    先枚举根节点,首先根节点为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

  • 部分代码
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;
}

by 路人七

上一篇:【NOIP2018】保卫王国 题解(树形DP+倍增)


下一篇:NOIP2018普及组摆渡车题解