Test instructions
Two trees (10^5 nodes) ask how many of them are isomorphic to each other
Ideas:
The isomorphism of a tree is generally judged by a hash.
The hash function is 1, val=a 2, val = (val*p) ^soni%q where Soni is the hash value of the sub-tree 3, Val=val*b%q
Note that the son value should be sorted (this is because the left and right subtrees are separated so they do not have to be sorted)
Code:
#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 1333333333333331LLint 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]);d FS (1,0 );d FS;p rintf ("%llu\n", ans); return 0;}
ZOJ 3602 Count the Trees