P5043 【模板】树同构([BJOI2015]树的同构)

传送门

把所有的树给哈希起来就好了
具体的方法是一个节点的哈希值就是它所有儿子的哈希值给哈希起来,然后以每个节点为根算出它作为根节点的哈希值。那么把每棵树的哈希值排个序,与之前的比较就好了
注意把儿子的哈希值给哈希起来的时候要把他们排个序

// luogu-judger-enable-o2
//minamoto
#include<bits/stdc++.h>
#define R register int
#define fp(i,a,b) for(R i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R i=a,I=b-1;i>I;--i)
#define go(u) for(R i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
    R res,f=1;char ch;
    while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
    for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
    return res*f;
}
const int N=1005,Base=233,P=998244353;
struct eg{int v,nx;}e[N];int head[N],tot;
inline void add(R u,R v){e[++tot]={v,head[u]},head[u]=tot;}
int n,m,q[N][N],ans[N][N],u;
int Hash(int u,int fa){
    int ans=N,top=0;
    go(u)if(v!=fa)q[u][++top]=Hash(v,u);
    sort(q[u]+1,q[u]+1+top);
    fp(i,1,top)ans=(1ll*ans*Base+q[u][i])%P;
    return (1ll*ans*Base+N+1)%P;
}
int main(){
//	freopen("testdata.in","r",stdin);
    m=read();
    fp(i,1,m){
        tot=0,n=read();fp(j,1,n)head[j]=0;
        fp(j,1,n)if((u=read()))add(u,j),add(j,u);
        fp(j,1,n)ans[i][j]=Hash(j,0);
        sort(ans[i]+1,ans[i]+n+1);
        for(R j=1,k=0;j<=i;++j){
            while(k<=n&&ans[i][++k]==ans[j][k]);
            if(k>n){printf("%d\n",j);break;}
        }
    }return 0;
}
posted @ 2018-12-04 12:37  bztMinamoto  阅读(227)  评论(0编辑  收藏  举报
Live2D