@[devinwang](/user/156004)
@[zaozao_zmx](/user/205356)
@[sunjialiang](/user/271277)
@[鸡巴毛](/user/229998)
@[dead_X](/user/111055)
by zhoukangyang @ 2019-11-15 18:53:40
你的dsy是根据每个子树重新做的,应该加memset清空过。但是这样就会超时。还是应该记录每个节点下的对称子树的大小
```cpp
#include<bits/stdc++.h>
using namespace std;
int n,d[1000001],son[1000001][2],ans,dsy[1000001],ss1,ss2,flag;
// void dfs1(int x,int t) {
// if(x==-1) return;
// ++ss1;
// dsy[ss1]=t*d[x];
// dfs1(son[x][1],1);
// dfs1(son[x][0],-1);
// }
// void dfs2(int x,int t) {
// if(x==-1) return;
// ++ss2;
// if(dsy[ss2]!=t*d[x]) {
// flag=1;
// return;
// }
// dfs2(son[x][0],1);
// dfs2(son[x][1],-1);
// }
void dfs(int x){
dsy[x]=1;//自己大小是1
if (son[x][0]!=-1){
dfs(son[x][0]);
dsy[x]+=dsy[son[x][0]];
}
if (son[x][1]!=-1){
dfs(son[x][1]);
dsy[x]+=dsy[son[x][1]];
}
//可以先深搜处理,左右子树的对称二叉树大小不同时,直接舍弃答案。
}
// int qwq(int x) {
// if(son[x][0]==-1&&son[x][1]==-1) return 1;//该点为叶子节点,是是对称的,大小为1
// //排除对称,其他事后如果有一边无子树,则不对称。
// if(son[x][0]==-1) return -1;
// if(son[x][1]==-1) return -1;
// flag=0;
// ss1=ss2=0;
// memset(dsy,0,sizeof(dsy));
// dfs1(son[x][0],1);//遍历左子树
// dfs2(son[x][1],1);
// if(ss1!=ss2) return -1;
// if(flag==1) return -1;
// return ss1*2+1;
// }
bool qwq(int x,int y) {
if(x==-1&&y==-1) return true;//该点为叶子节点,是是对称的,大小为1
//排除对称,其他事后如果有一边无子树,则不对称。
if(x==-1) return false;
if(y==-1) return false;
if (d[x]==d[y]&&qwq(son[x][0],son[y][1])&&qwq(son[x][1],son[y][0]))
return true;
return false;
}
int main() {
scanf("%d",&n);
for(int i = 1; i <= n; i++) {
scanf("%d",&d[i]);
}
for(int i = 1; i <= n; i++) {
scanf("%d%d",&son[i][0],&son[i][1]);//son[i][0]左孩子,son[i][1]右孩子
}
dfs(1);
for(int i = 1; i <= n; i++) {
if (qwq(son[i][0],son[i][1]))
ans=max(ans,dsy[i]);
}
printf("%d",ans);
return 0;
}
```
by devinwang @ 2019-12-07 00:20:05
谢谢王老师!
=
by zhoukangyang @ 2019-12-07 09:55:41