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

题面:

  树是一种很常见的数据结构。

  我们把N个点,N1条边的连通无向图称为树。

  若将某个点作为根,从根开始遍历,则其它的点都有一个前驱,这个树就成为有根树。

  对于两个树T1T2,如果能够把树T1的所有点重新标号,使得树T1和树T2完全相同,那么这两个树是同构的。也就是说,它们具有相同的形态。

  现在,给你M个有根树,请你把它们按同构关系分成若干个等价类。

 

无根树Hash。。。

以树的每一个节点为根,求出Hash值后,存入一个数组里,排序。

比对就像这样

  

for(int j=1;j<=i;j++){
    bool flag=0;
    for(int k=1;k<=n;k++) if(H[i][k]!=H[j][k]) flag=1;
    if(!flag) {printf("%d\n",j);break;}
    } 

 

至于怎样求以一个节点为根时树的Hash值,

先把它的子节点的Hash值存入一个vector里,排序,然后就像字符串Hash一样,求就完事了,叶子节点返回 1 。

ll dfs(int x,int fa){
    ll res=1;vector<ll> v;
    for(int i=Head[x];i;i=nex[i]){
        int y=ver[i];if(y==fa) continue;
        v.push_back(dfs(y,x));
    }
    sort(v.begin(),v.end());
    for(unsigned int i=0;i<v.size();i++) res=(res*P+v[i])%mod;
    return res%mod;
}

 

然后就能切掉了啦。

一开始我找树的重心,然后像上面那样求以重心为根节点的Hash值,由于可能有2个重心,取较小值即可。然而只有30pts。QAQ。。。。。。

 

posted @ 2019-10-15 11:59  dzzx_Syh  阅读(114)  评论(0编辑  收藏  举报