当前位置:   article > 正文

洛谷 P5018 [NOIP2018 普及组] 对称二叉树 题解

洛谷 P5018 [NOIP2018 普及组] 对称二叉树 题解

传送门:[NOIP2018 普及组] 对称二叉树 - 洛谷

老样子,先建树

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int n;
  4. struct node
  5. {
  6. long long l,r,val;
  7. }bt[1000002];//val表示点权,l表示左子树索引,r表示右子树索引
  8. int main()
  9. {
  10. cin>>n;
  11. for(int i=1;i<=n;i++)cin>>bt[i].val;
  12. for(int i=1;i<=n;i++)cin>>bt[i].l>>bt[i].r;//按题目要求输入
  13. return 0
  14. }

一.大致思路

题目要求我们求给定的树的最大对称二叉子树的节点数,那么我们就以[1,n]为子树的根节点,DFS该子树是否为对称二叉树,再进行节点的计数

二.分解

1.检查是否为对称二叉树

搜索的DFS函数为bool函数,返回值为true则为对称二叉树,false就不是。我们就从该子树的根节点开始搜索,以lnowrnow为向其左右子树搜索的节点编号,那么就分为两部分检查:

1.结构

2.权值

检查结构时,要么全是-1(空),要么全是编号(都有子树),否则就是结构不完整,直接返回false,当然如果全是-1,就不能再搜了(边界),返回true。

权值不必多说,不相等就返回false。

如果没问题就进行进一步的搜索,注意:如果当lnow向左搜时,rnow向右搜,当lnow向右搜时,rnow向左搜以满足其对称性!

如果上述两种搜索方式返回true,则该树为对称二叉树,返回true。

  1. bool same(long long lnow,long long rnow)
  2. {
  3. if(lnow==-1&&rnow==-1)return true;
  4. if(lnow==-1||rnow==-1)return false;//结构检查
  5. if(bt[lnow].val!=bt[rnow].val) return false;//权值检查
  6. return same(bt[lnow].l,bt[rnow].r)&&same(bt[lnow].r,bt[rnow].l);//向下搜索
  7. }

2.节点计数

该函数为int类型,返回节点数,对于一个节点pos,其节点及其子树的节点和为其本身的一个节点,以及其左、右子树的节点数,递归边界为pos!=1(不为子节点)

  1. int count(long long pos)
  2. {
  3. if(pos==-1)return 0;
  4. else return count(bt[pos].l)+count(bt[pos].r)+1;
  5. }

三.总代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int n,ans;//ans记录答案
  4. struct node
  5. {
  6. long long l,r,val;
  7. }bt[1000002];
  8. bool same(long long lnow,long long rnow)
  9. {
  10. if(lnow==-1&&rnow==-1)return true;
  11. if(lnow==-1||rnow==-1)return false;
  12. if(bt[lnow].val!=bt[rnow].val) return false;
  13. return same(bt[lnow].l,bt[rnow].r)&&same(bt[lnow].r,bt[rnow].l);
  14. }
  15. int count(long long pos)
  16. {
  17. if(pos==-1)return 0;
  18. else return count(bt[pos].l)+count(bt[pos].r)+1;
  19. }
  20. int main()
  21. {
  22. cin>>n;
  23. for(int i=1;i<=n;i++)cin>>bt[i].val;
  24. for(int i=1;i<=n;i++)cin>>bt[i].l>>bt[i].r;
  25. for(int i=1;i<=n;i++)if(same(i,i))ans=max(ans,count(i));
  26. cout<<ans;
  27. return 0;
  28. }

 AC!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/731945
推荐阅读
相关标签
  

闽ICP备14008679号