zoj 3602

链接

[https://vjudge.net/contest/293343#problem/C]

题意

给你两棵树。为有多少对子树是同构的

分析

就是简单的哈希吧。对于不同结构的树对应不同的哈希值
先明确同构是指它左右儿子都一样
所以这么映射 map<pair<int,int>,int> mp;最后一个值表示哈希值
然后先扫描第一棵树。统计每种结构的数量
扫描第二颗树的时候,就可以统计了。对于每种结构
就是两边的该结构数量的乘积,但这里不必统计第二颗树的了。你遇到该结构
就加就完事了。比如5*4就等于4个5相加

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+10;
map<pair<int,int>,int > mp;
//代表lson,rson对应的哈希值 
ll sum;
int Type;
int a[2][N],b[2][N];
ll num[N];
int dfs1(int x){
    int ls,rs;
    if(a[0][x]!=-1)
    ls=dfs1(a[0][x]);
    else ls=-1;
    if(a[1][x]!=-1)
    rs=dfs1(a[1][x]);
    else rs=-1;
    if(mp[make_pair(ls,rs)]==0) mp[make_pair(ls,rs)]=++Type;
    int curtype=mp[make_pair(ls,rs)];
    num[curtype]++;
    return curtype; 
}
int dfs2(int y){
    int ls,rs;
    if(b[0][y]!=-1)
    ls=dfs2(b[0][y]);
    else ls=-1;
    if(b[1][y]!=-1)
    rs=dfs2(b[1][y]);
    else rs=-1;
    int curtype=mp[make_pair(ls,rs)]; 
    sum+=num[curtype];
    return curtype;
}
int main(){
    int t,n,m;
    scanf("%d",&t);
    while(t--){
        memset(num,0,sizeof(num));
        mp.clear();
        sum=0,Type=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        scanf("%d%d",&a[0][i],&a[1][i]);
        for(int j=1;j<=m;j++)
        scanf("%d%d",&b[0][j],&b[1][j]);
        dfs1(1);dfs2(1);
        printf("%lld\n",sum);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/mch5201314/p/10697891.html
ZOJ
今日推荐