题解 对称二叉树
题面
解析
这题看上去好像很复杂(实际上也很复杂)。。。
但仔细想想,
若以一个点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 }