zoukankan      html  css  js  c++  java
  • 【洛谷p5018】对称二叉树

    对称二叉树【题目链接】

    然后废话:

    这道题是一道很神奇的dfs?(算是吧)然后是wxl学长讲的;

    SOLUTION:

    首先解释一下对称二叉树:

    你看这棵树,最大的对称二叉树节点数为3,然后可能会误会成id 8,5,6,但是实际上指的是id 7,3,5。因为对称二叉树的要求是:

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

    可以理解为轴对称;

    好了没有然后了(jiushiweilecougezishu

    首先是读入,因为是二叉树,所以直接存左右鹅子开一个二维数组,第二维0表示左儿子,1表示右儿子。然后分别读入就好啦。

    大框架:

    memset(son,-1,sizeof(son));

    读入:

    ……

    dfs(1);

    枚举以每个点为根的子树;

    如果满足对称二叉树的要求,与当前最大值比较,取更大的那个;

    输出;

    然后是dfs记录每个子树的节点个数(这个用于最后枚举以每个节点为根的子树满足条件后,求最大值用的)

    void dfs(int u){
        size[u]=1;//本身节点有1
        if(son[u][0]!=-1){//判断有木有左鹅子
            dfs(son[u][0]);//如果有递归左鹅子
            size[u]+=size[son[u][0]];//当前节点size+=左鹅子节点size
        }//右鹅子同理
        if(son[u][1]!=-1){
            dfs(son[u][1]);
            size[u]+=size[son[u][1]];
        }
        return;
    }

    然后核心代码就是check了:

    这里check是递归的check的;

    当一个节点i既没有左儿子也没有右儿子,显然它是个叶子,那么它肯定对称,return 1;

    当一个节点i既有左儿子又有右儿子,并且左右儿子权值相等时,我们递归的比较(左儿子的右儿子,右儿子的左儿子)比较(右儿子的右儿子,左儿子的左儿子),如果比到叶节点仍然相同,就可以认为以i为根的子树是轴对称的对称二叉树。其他只要有一点不满足,就一定不是对称二叉树。

    bool check(int u,int v){
        if(u==-1&&v==-1) return 1;
        if(u!=-1&&v!=-1&&val[u]==val[v]&&check(son[u][1],son[v][0])&&check(son[u][0],son[v][1]))
          return 1;
        return 0;
    }

    最后上面写了吧↑

    CODE:

    #include<bits/stdc++.h>
    
    using namespace std;
    
    inline int read(){
        int ans=0;
        char last=' ',ch=getchar();
        while(ch<'0'||ch>'9') last=ch,ch=getchar();
        while(ch>='0'&&ch<='9') ans=(ans<<1)+(ans<<3)+ch-'0',ch=getchar();
        if(last=='-') ans=-ans;
        return ans;
    }
    
    int n;
    int val[1000005],son[1000005][2],size[1000005];
    
    void dfs(int u){
        size[u]=1;
        if(son[u][0]!=-1){
            dfs(son[u][0]);
            size[u]+=size[son[u][0]];
        }
        if(son[u][1]!=-1){
            dfs(son[u][1]);
            size[u]+=size[son[u][1]];
        }
        return;
    }
    
    bool check(int u,int v){
        if(u==-1&&v==-1) return 1;
        if(u!=-1&&v!=-1&&val[u]==val[v]&&check(son[u][1],son[v][0])&&check(son[u][0],son[v][1]))
          return 1;
        return 0;
    }
    
    int main(){
        memset(son,-1,sizeof(son));
        n=read();
        for(int i=1;i<=n;i++)
          val[i]=read();
        for(int i=1;i<=n;i++){
            son[i][0]=read();
            son[i][1]=read();
        }
        dfs(1);
        int ans=0;
        for(int i=1;i<=n;i++){
            if(check(son[i][0],son[i][1]))
            ans=max(ans,size[i]);
        }
        cout<<ans<<endl;
        return 0;
    }

    end-

  • 相关阅读:
    [Evolution in aciton] C#1.1=>2.0=>3.0 [Querying Collections]
    动态操作.Config文件
    设计模式代理模式(Proxy Model)
    Linq Coding Part Five (Join之内部联接查询)
    Linq Coding Part Four[Concat应用]
    [转]领域模型管理与AOP
    08端午节,休闲一下吧,来上游戏
    有关于ViewState的二种压缩方式
    AddOutParameter引发类型问题
    Linq Coding Part Two[标准查询运算符]
  • 原文地址:https://www.cnblogs.com/zhuier-xquan/p/11116035.html
Copyright © 2011-2022 走看看