bzoj4337: BJOI2015 树的同构
hash大法好
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #define N 55 #define M 105 using namespace std; inline int read(){ int ret=0;char ch=getchar(); while (ch<'0'||ch>'9') ch=getchar(); while ('0'<=ch && ch<='9'){ ret=ret*10-48+ch; ch=getchar(); } return ret; } const int pri[49]={2,23,29,37,53,67,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229, 233,239,241,251,257,263,269,271,277,281,283,293,307}; struct edge{ int adj,next; edge(){} edge(int _adj,int _next):adj(_adj),next(_next){} } e[M]; int n,g[N],m; void AddEdge(int u,int v){ e[++m]=edge(v,g[u]);g[u]=m; e[++m]=edge(u,g[v]);g[v]=m; } unsigned int data[N]; bool vis[N]; void dfs(int u){ vis[u]=1; int p=0; unsigned int d[N]; d[p++]=1; for (int i=g[u];i;i=e[i].next){ int v=e[i].adj; if (vis[v]) continue; dfs(v); d[p++]=data[v]; } sort(d,d+p); data[u]=0; for (int i=0;i<p;++i) data[u]+=d[i]*pri[i]; } int num[N]; unsigned int hash[N][N]; int main(){ int tot=read(); for (int j=1;j<=tot;++j){ n=num[j]=read(); int root; memset(g,0,sizeof(g));m=1; for (int i=1;i<=n;++i){ int fa=read(); if (fa) AddEdge(fa,i); } for (int i=1;i<=n;++i){ memset(vis,0,sizeof(vis)); dfs(i); hash[j][i]=data[i]; } sort(hash[j]+1,hash[j]+n+1); for (int i=1;i<=j;++i) if (num[i]==num[j]){ int k=1; for (;k<=n;++k) if (hash[i][k]!=hash[j][k]) break; if (k>n){ printf("%d\n",i); break; } } } return 0; }