ZOJ3602:Count the Trees
我是在neuqvj上交的这题:http://vj.acmclub.cn/problem/viewProblem.action?id=17848
本来是挺容易的树同构题,可是节点数比较多,愣是把普通hash卡掉了(出题人麻烦您过来一下)
只能用map映射一下,给每个状态一个标号,而状态的表示是它两个儿子的标号。
#include<map> #include<cstdio> #include<cstring> #include<algorithm> #define MN 110001 #define ll long long #define fi first #define se second using namespace std; int read_p,read_ca,read_f; inline int read(){ read_p=0;read_ca=getchar();read_f=1; while(read_ca<'0'||read_ca>'9') read_f=read_ca=='-'?-1:read_f,read_ca=getchar(); while(read_ca>='0'&&read_ca<='9') read_p=read_p*10+read_ca-48,read_ca=getchar(); return read_p*read_f; } const int HA=1e6+7; int T,n,m,ha[MN],a,b,L[MN],R[MN],nm=0,mmh[2][MN]; ll MMH; map<pair<int,int>,int>mp; int dfs(int x,int mmh[]){ int MMH; pair<int,int> now=make_pair(L[x]==-1?0:dfs(L[x],mmh),R[x]==-1?0:dfs(R[x],mmh)); if (mp.find(now)==mp.end()) MMH=mp[now]=++nm;else MMH=mp[now]; mmh[MMH]++; return MMH; } inline void work(int n,int mmh[]){ for (int i=1;i<=n;i++) L[i]=read(),R[i]=read(); dfs(1,mmh); } int main(){ T=read(); for (int i=0;i<MN;i++) ha[i]=rand()%HA; while (T--){ nm=0;mp.clear(); memset(mmh,0,sizeof(mmh)); n=read();m=read();MMH=0; work(n,mmh[0]); work(m,mmh[1]); for (int i=1;i<=nm;i++) MMH+=1LL*mmh[0][i]*mmh[1][i]; printf("%lld\n",MMH); } }