84分,求巨佬们帮忙

P5018 [NOIP2018 普及组] 对称二叉树

@[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


|