如果一个二叉树是对称的,那么对于深度相同的两个节点u,v,必定有lson(u)与rson(v),rson(u)与lson(v),并且val(u)=val(v)
,因此我们就可以写出这一份看起来像是暴力的正解:枚举以i为根的二叉树,是不是对称二叉树
#include<bits/stdc++.h>
using namespace std;
struct node//存储边的关系
{
int ls;
int rs;
}edge[1000010];
int n,a[1000010],vis[1000010],sontree[1000010],ans;
inline int read()//快读
{
int f=1,res=0;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
while(isdigit(ch)){res=(res<<1)+(res<<3)+(ch&15);ch=getchar();}
return res*f;
}
inline void findsontree(int x)
{
if(!edge[x].ls&&!edge[x].rs)return;//找到叶节点
if(edge[x].ls)findsontree(edge[x].ls);//有左儿子就递归
if(edge[x].rs)findsontree(edge[x].rs);//有右儿子就递归
sontree[x]+=sontree[edge[x].ls]+sontree[edge[x].rs];//树的大小等于左儿子大小+右儿子的大小
}
inline bool dfs(int x,int y)
{
if(a[x]!=a[y])return 0;//如果点的权值不同,不对称
if(!edge[x].ls&&!edge[x].rs&&!edge[y].ls&&!edge[y].rs)return 1;//到叶节点还没有返回,对称
if(dfs(edge[x].ls,edge[y].rs)&&dfs(edge[x].rs,edge[y].ls))return 1; //如果左儿子和右儿子都对称,那么对称
}
int main()
{
n=read();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<=n;i++)//读入信息
{
int x,y;
x=read();y=read();
if(x==-1&&y==-1)vis[i]=1;
if(x<0)x=0;
if(y<0)y=0;
edge[i].ls=x;
edge[i].rs=y;
}
for(int i=1;i<=n;i++)sontree[i]=1;//至少一个大小
findsontree(1);
for(int i=1;i<=n;i++)
if(dfs(edge[i].ls,edge[i].rs))//对称
ans=max(ans,sontree[i]);//打擂台
cout<<ans;
return 0;
}
/*
10
2 2 5 5 5 5 4 4 2 3
9 10
-1 -1
-1 -1
-1 -1
-1 -1
-1 2
3 4
5 6
-1 -1
7 8
*/