80分求助QWQ

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

@[zinuo](/user/104775) 能讲讲思路吗,我想做这题但不会做QwQ
by lion0514 @ 2020-10-24 07:54:26


~~蒟蒻的垃圾思路~~ ## 就是先把从所有一个点开始的子树有几个节点算出来(可以记忆化) ```cpp void dfs(int k){ use[k] = 1; if(son[k][0] != -1){ dfs(son[k][0]); use[k] += use[son[k][0]]; } if(son[k][1] != -1){ dfs(son[k][1]); use[k] += use[son[k][1]]; } return; } ``` ## 再去判断从这个点的子树是否合法 ```cpp bool jub(int l, int r){ if(l == -1 && r == -1) return 1; if(l != -1 && r != -1 && jub(son[l][0],son[r][1]) && jub(son[l][1], son[r][0]) && num[l] == num[r]) return 1; return 0; } ``` ## 然后是代码 ``` #include<cstdio> #include<cstdlib> typedef long long lld; const lld N = 1000011; lld son[N][2]; lld ans = -1, num[N], use[N]; lld n; lld max(lld a, lld b) { return (a < b) ? b : a; } lld read(){ lld x = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while('0' <= ch && ch <= '9'){ x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar(); } return x * f; } void dfs(int k){ use[k] = 1; if(son[k][0] != -1){ dfs(son[k][0]); use[k] += use[son[k][0]]; } if(son[k][1] != -1){ dfs(son[k][1]); use[k] += use[son[k][1]]; } return; } bool jub(int l, int r){ if(l == -1 && r == -1) return 1; if(l != -1 && r != -1 && jub(son[l][0],son[r][1]) && jub(son[l][1], son[r][0]) && num[l] == num[r]) return 1; return 0; } int main(){ //freopen("tree.in", "r", stdin); //freopen("tree.out", "w", stdout); n = read(); for (int i = 1; i <= n; i++) num[i] = read(); for (int i = 1; i <= n; i++) son[i][0] = read(), son[i][1] = read(); dfs(1); for (int i = 1; i <= n; i++) if (jub(son[i][0], son[i][1])) ans = max(ans, use[i]); printf("%lld\n", ans); } ``` ## 不喜勿喷谢谢
by Soul_hunter @ 2020-11-04 10:13:33


|