[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;
}
原文:https://www.cnblogs.com/mch5201314/p/10697891.html