构造一个靠谱点的树哈希函数,每个树以每个点都为根算一次哈希值,然后归类一下有相同哈希值的树就行了。
代码
1 #include<cstdio> 2 #include<algorithm> 3 #define nc() getchar() 4 #define N 500100 5 int dp,pre[N],p[N],ans[N],tt[N],n,i,m[N],a,j,k; 6 long long q,hash[N],s[N],v[N]; 7 void link(int x,int y) 8 { 9 dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y; 10 } 11 void root(int x,int fa) 12 { 13 int i=p[x]; 14 long long ans=1; 15 s[x]=1; 16 while (i) 17 { 18 if (tt[i]!=fa) 19 { 20 root(tt[i],x); 21 long long tmp=v[tt[i]]+131; 22 s[x]=s[x]+s[tt[i]]; 23 v[x]=v[x]+tmp; 24 } 25 i=pre[i]; 26 } 27 v[x]=v[x]*s[x]%1000000007; 28 } 29 int main() 30 { 31 scanf("%d",&n); 32 for (i=1;i<=n;i++) 33 { 34 scanf("%d",&m[i]); 35 dp=0; 36 for (j=1;j<=m[i];j++) p[j]=0; 37 for (j=1;j<=m[i];j++) 38 { 39 scanf("%d",&a); 40 if (a) 41 { 42 link(a,j); 43 link(j,a); 44 } 45 } 46 47 for (j=1;j<=m[i];j++) 48 { 49 for (k=1;k<=m[i];k++) 50 s[k]=0,v[k]=0; 51 root(j,0);q=v[j]; 52 for (k=1;k<i;k++) 53 if ((m[k]==m[i])&&(hash[k]==q)) 54 { 55 ans[i]=k;break; 56 } 57 } 58 if (ans[i]==0) ans[i]=i,hash[i]=q; 59 60 } 61 for (i=1;i<=n;i++) 62 printf("%d ",ans[i]); 63 }