zoukankan      html  css  js  c++  java
  • zoj 3602

    给你两颗二叉树,左右子树不可旋转,求这两个棵树相同的子树的个数。可以给每一种子树的形态一个编号,那么我们只要统计第一个颗树中每种形态的子树有多少个,然后把第二颗树中相同子树的数目与之相乘就可以了。我们可以设定叶子节点的形态编号为0,用一个map来存放hash值,而任何一个节点的哈希值都可用左右子树的形态编号形成的pair唯一表示。

    View Code
      1 // File Name: 3602.cpp
      2 // Author: Missa
      3 // Created Time: 2013/2/5 星期二 11:47:26
      4 
      5 #include<iostream>
      6 #include<cstdio>
      7 #include<cstring>
      8 #include<algorithm>
      9 #include<cmath>
     10 #include<queue>
     11 #include<stack>
     12 #include<string>
     13 #include<vector>
     14 #include<cstdlib>
     15 #include<map>
     16 using namespace std;
     17 const int maxn = 1e5+5;
     18 struct node
     19 {
     20     int l,r;
     21     node(){}
     22     node(int l,int r):l(l),r(r){}
     23 }t1[maxn],t2[maxn];
     24 int n,m;
     25 bool operator <(const node&a,const node &b)
     26 {
     27     if(a.l==b.l) return a.r<b.r;
     28     return a.l<b.l;
     29 }
     30 int ord[maxn];//bfs一次形成的顺序
     31 int o_num;
     32 map<node,int>ha,cnt;//ha用来判断同构,cnt用来计数
     33 int st[maxn];//节点的形态
     34 void build()
     35 {
     36     queue<int>q;
     37     while(!q.empty()) q.pop();
     38     ha.clear();
     39     cnt.clear();
     40     q.push(1);
     41     o_num=0;
     42     while(!q.empty())
     43     {
     44         int cur=q.front();q.pop();
     45         ord[o_num++]=cur;
     46         if(t1[cur].l>0) q.push(t1[cur].l);
     47         if(t1[cur].r>0) q.push(t1[cur].r);
     48     }
     49     int type=0;
     50     memset(st,0,sizeof(st));
     51     for(int i=n-1;i>=0;i--)
     52     {
     53         int tmp=ord[i];
     54         int ll=t1[tmp].l>0?st[t1[tmp].l]:0;
     55         int rr=t1[tmp].r>0?st[t1[tmp].r]:0;
     56         node p=node(ll,rr);
     57         if(ha.find(p)==ha.end())
     58             ha[p]=++type;
     59         st[ord[i]]=ha[p];
     60         cnt[p]++;
     61     }
     62     //cout<<"mark\n";
     63 }
     64 void gao()
     65 {
     66     queue<int>q;
     67     while(!q.empty()) q.pop();
     68     q.push(1);
     69     o_num=0;
     70     while(!q.empty())
     71     {
     72         int cur=q.front();q.pop();
     73         ord[o_num++]=cur;
     74         if(t2[cur].l>0) q.push(t2[cur].l);
     75         if(t2[cur].r>0) q.push(t2[cur].r);
     76     }
     77     memset(st,0,sizeof(st));
     78     long long ans=0;
     79     for(int i=m-1;i>=0;i--)
     80     {
     81         int tmp=ord[i];
     82         int ll=t2[tmp].l>0?st[t2[tmp].l]:0;
     83         int rr=t2[tmp].r>0?st[t2[tmp].r]:0;
     84         node p=node(ll,rr);
     85         if(ha.find(p)==ha.end())
     86         {
     87             st[tmp]=-1;
     88             continue;
     89         }
     90         ans+=cnt[p];
     91         st[tmp]=ha[p];
     92     }
     93     printf("%lld\n",ans);
     94 }
     95 
     96 int main()
     97 {
     98     int test;
     99     scanf("%d",&test);
    100     while(test--)
    101     {
    102         scanf("%d%d",&n,&m);
    103         memset(t1,-1,sizeof(t1));
    104         memset(t2,-1,sizeof(t2));
    105         for(int i=1;i<=n;i++)
    106             scanf("%d%d",&t1[i].l,&t1[i].r);
    107         for(int i=1;i<=m;i++)
    108             scanf("%d%d",&t2[i].l,&t2[i].r);
    109         //cout<<"r\n";
    110         build();
    111         gao();
    112     }
    113     return 0;
    114 }
  • 相关阅读:
    Linux chattr 文件保护
    ArcGIS案例学习笔记-批处理擦除挖空挖除相减
    ArcGIS案例学习笔记-手动编辑擦除挖空挖除相减
    GIS案例学习笔记-CAD数据分层导入现有模板实例教程
    GIS案例学习笔记-ArcGIS整图大图出图实例教程
    Arcgis map export or print Error: Cannot map metafile into memory. Not enough memory
    [图解tensorflow源码] 入门准备工作附常用的矩阵计算工具[转]
    GIS案例学习笔记-明暗等高线提取地理模型构建
    地理处理模型、案例、教程、培训低价发送
    GIS工具-shp浏览器
  • 原文地址:https://www.cnblogs.com/Missa/p/2892925.html
Copyright © 2011-2022 走看看