BZOJ4337:[BJOI2015]树的同构——题解

https://www.lydsy.com/JudgeOnline/problem.php?id=4337

树是一种很常见的数据结构。
我们把N个点,N-1条边的连通无向图称为树。
若将某个点作为根,从根开始遍历,则其它的点都有一个前驱,这个树就成为有根树。
对于两个树T1和T2,如果能够把树T1的所有点重新标号,使得树T1和树T2完全相
同,那么这两个树是同构的。也就是说,它们具有相同的形态。
现在,给你M个有根树,请你把它们按同构关系分成若干个等价类。

Q:如何树哈希啊。

A:网上也没有讲解啊,不如看看代码理解一下吧……我就是这么干的。

代码抄自:https://blog.csdn.net/CHNWJD/article/details/78264934当然是没有讲解的。

要注意dfs里的ans一定要有初值!

#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef unsigned long long ll;
const int N=51;
const int B=911;
const int p[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,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};
inline int read(){
    int X=0,w=0;char ch=0;
    while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
    while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
struct node{
    int to,nxt;
}e[N*2];
int n[N],m,cnt,head[N];
ll ha[N][N];
inline void add(int u,int v){
    e[++cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt;
}
int dfs(int u,int fa){
    ll num[N],ans=B;int tot=0;
    for(int i=head[u];i;i=e[i].nxt){
    int v=e[i].to;
    if(v==fa)continue;
    num[++tot]=dfs(v,u);
    }
    sort(num+1,num+tot+1);
    for(int i=1;i<=tot;i++)ans=ans*B+num[i]*p[i];
    return ans;
}
int main(){
    m=read();
    for(int i=1;i<=m;i++){
    n[i]=read();cnt=0;
    memset(head,0,sizeof(head));
    for(int j=1;j<=n[i];j++){
        int v=read();
        if(v)add(j,v),add(v,j);
    }
    for(int j=1;j<=n[i];j++)ha[i][j]=dfs(j,0);
    sort(ha[i]+1,ha[i]+n[i]+1);
    bool flag=0;
    for(int j=1;j<=i&&!flag;j++)
        if(n[i]==n[j])
        for(int k=1;k<=n[i];k++){
            if(ha[i][k]!=ha[j][k])break;
            if(k==n[i]){
            printf("%d\n",j);
            flag=1;
            }
        }
    }
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

posted @ 2018-06-11 19:59  luyouqi233  阅读(257)  评论(0编辑  收藏  举报