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

Posted syhakioi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
",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。。。。。。

 

以上是关于luogu P5043 模板树同构([BJOI2015]树的同构)的主要内容,如果未能解决你的问题,请参考以下文章

P5043 模板树同构([BJOI2015]树的同构) |树哈希

树同构/树哈希

Luogu P4323 [JSOI2016]独特的树叶

4337. [BJOI2015]树的同构树哈希

树hs[BJOI2015]树的同构

[BJOI2015]树的同构 && 树哈希教程