• 对称二叉树


    洛咕

    题意:定义对称二叉树满足如下两个条件:

    1.是一棵二叉树.

    2.将这棵树所有节点的左右子树交换,新树和原树对应位置的结构相同且点权相等.

    给定一棵(n(n<=1e6))个节点的树,求最大的对称二叉树的大小(包含节点个数).叶节点也是一棵对称二叉树.

    分析:仔细分析不难发现,如果是对称二叉树,要满足如下几个条件:

    1.左右儿子节点的权值相同.

    2.左右儿子的子树大小相同(这个我们跑一遍DFS,预处理出每个节点的(size)就好了).

    3.左儿子的左子树与右儿子的右子树也满足对称.左儿子的右子树与右儿子的左子树也满足对称(这个显然是另一个子问题,所以递归来做就好了)

    综上所述,我们先从根节点1开始拍一遍(DFS),预处理每个节点的(size).然后扫描n个节点,对于每个节点i,都像上面那样去判断是否满足对称二叉树的条件,如果满足就更新(ans.)

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=1e6+5;
    int w[N],l[N],r[N],size[N];
    inline void dfs(int u){
    	size[u]=1;
    	if(l[u]!=-1){
    		dfs(l[u]);
    		size[u]+=size[l[u]];
    	}
    	if(r[u]!=-1){
    		dfs(r[u]);
    		size[u]+=size[r[u]];
    	}
    }
    inline bool check(int u,int v){
    	if(u==-1&&v==-1)return true;
    	if(w[u]==w[v]&&size[u]==size[v]&&check(l[u],r[v])&&check(r[u],l[v]))return true;
    	return false;
    }
    int main(){
    	int n=read();
    	for(int i=1;i<=n;++i)w[i]=read();
    	for(int i=1;i<=n;++i)l[i]=read(),r[i]=read();
    	dfs(1);int ans=1;
    	for(int i=1;i<=n;++i)if(check(l[i],r[i]))ans=max(ans,size[i]);
    	printf("%d
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    Linux搭建ElasticSearch环境
    从DDD开始说起
    TFS看板晨会
    TFS看板的迭代规划
    TFS看板规则
    TFS看板的设计
    Api容器在应用架构演化中的用途
    基于Abp的WebApi容器
    线程队列
    动态类型序列化
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11552970.html
Copyright © 2020-2023  润新知