首页 > 代码库 > ZOJ 3602 Count the Trees
ZOJ 3602 Count the Trees
题意:
两棵树(10^5个节点) 问其中有多少对子树是同构的
思路:
树的同构一般使用hash来判断
hash函数为1、val=A 2、val = (val*P)^Soni%Q 其中Soni为第i个子树的hash值 3、val=val*B%Q
注意Son值应该排序 (本题因为左右子树是区分开的 因此不用排序)
代码:
#include<cstdio> #include<iostream> #include<cstring> #include<string> #include<algorithm> #include<map> #include<set> #include<vector> #include<queue> #include<cstdlib> #include<ctime> #include<cmath> using namespace std; typedef unsigned long long ULL; #define N 100010 #define A 1333333331LL #define B 1333333333331LL #define P 133331LL #define Q 1333333333333331LL int T,n,m; int l[2][N],r[2][N]; ULL ans; map<ULL,ULL> cnt; ULL dfs(int u,int f){ ULL val=A; if(l[f][u]!=-1){ ULL tmp=dfs(l[f][u],f); val=((val*P)^tmp)%Q; }else{ ULL tmp=(A&B^P); val=((val*P)^tmp)%Q; } if(r[f][u]!=-1){ ULL tmp=dfs(r[f][u],f); val=((val*P)^tmp)%Q; }else{ ULL tmp=(A&B^P); val=((val*P)^tmp)%Q; } if(!f) cnt[val]++; else ans+=cnt[val]; return val; } int main(){ scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); cnt.clear(); ans=0; for(int i=1;i<=n;i++) scanf("%d%d",&l[0][i],&r[0][i]); for(int i=1;i<=m;i++) scanf("%d%d",&l[1][i],&r[1][i]); dfs(1,0); dfs(1,1); printf("%llu\n",ans); } return 0; }
ZOJ 3602 Count the Trees
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。