思路:
先求每个节点的子树的个数,然后暴力枚举每个节点,找到左右子树对称的最多节点个数的就行。
判断子树是否对称:
先判断左右子树的值是否相同,然后递归判断左子树的左子树和右子树的右子树,和左子树的右子树和右子树的左子树是否相同即可。
代码:
#include<iostream> #include<vector> #include<cstring> #include<algorithm> using namespace std; const int maxn = 2e6 + 10; int va[maxn]; vector<int>G[maxn]; int son[maxn]; void dfs(int u){ son[u] = 1; for(int i = 0; i < 2; i++){ int v = G[u][i]; if(v != -1){ dfs(v); son[u] += son[v]; } } } bool check(int u,int v){ if(u == -1 && v == -1) return true; if(u != -1 && v != -1 && va[u] == va[v] && check(G[u][1],G[v][0]) && check(G[u][0],G[v][1])) return true; return false; } int main(){ int n;scanf("%d",&n); for(int i = 1; i <= n; i++)scanf("%d",&va[i]); for(int i = 1; i <= n; i++){ int l,r;scanf("%d%d",&l,&r); G[i].push_back(l); G[i].push_back(r); } dfs(1); int ans = 0; for(int i = 1; i <= n; i++) if(check(G[i][0],G[i][1])) ans = max(ans,son[i]); cout<<ans<<endl; return 0; }