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;
}
posted @ 2019-04-12 18:55  ChunhaoMo  阅读(114)  评论(0编辑  收藏  举报