博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

题解 对称二叉树

题面

 

 

解析

这题看上去好像很复杂(实际上也很复杂)。。。

但仔细想想,

若以一个点v为根的子树为对称二叉树,

则它的左子树lson和右子树rson一定是对称的,即:

lson的左子树和rson的右子树是对称的且lson的右子树和rson的左子树是对称的。

看出规律了吧,

这样只要递归求解就行了!!

终止条件就应该是:lson=rson=-1;

然后,先遍历一遍,求出以每个点为根的节点数目,再枚举就能AC了!!

 

 

上AC代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 struct tree{
 5     int ls,rs;
 6     int w,sonsum;
 7     int id;
 8 };
 9 tree a[1000001];
10 int n;
11 int ls=0,rs=1,ans=0;
12 
13 bool dfs(int x,int y){
14     if(x==-1&&y==-1) return 1;
15     else if(x==-1||y==-1) return 0;
16     int xl=a[x].ls,xr=a[x].rs;
17     int yl=a[y].ls,yr=a[y].rs;
18     if(dfs(xl,yr)&&dfs(xr,yl)){
19         if(a[x].w==a[y].w) return 1;
20     }
21     return 0;
22 }
23 
24 int find(int x){
25     if(x==-1) return 0;
26     a[x].sonsum=find(a[x].ls)+find(a[x].rs);
27     return ++a[x].sonsum;
28 }
29 
30 int main(){
31     scanf("%d",&n);
32     for(int i=1;i<=n;i++){
33         scanf("%d",&a[i].w);
34         a[i].id=i;
35     }
36     for(int i=1;i<=n;i++){
37         scanf("%d%d",&a[i].ls,&a[i].rs);
38     }
39     find(1);
40     for(int i=1;i<=n;i++){
41         if(dfs(a[i].ls,a[i].rs)){
42             ans=max(ans,a[i].sonsum);
43         }
44     }
45     printf("%d\n",ans);
46     return 0;
47 }

 

posted @ 2019-03-05 13:24  Hastin  阅读(190)  评论(0编辑  收藏  举报