哈希算法在判定树同构方面的应用(上)

本文介绍了哈希算法在判定树同构问题中的应用,包括树的重心概念和性质,以及如何通过哈希函数判断两棵有根树或无根树是否同构。文章提供了基于哈希的判定方法,并讨论了优化策略,如利用树的重心来减少时间复杂度。
摘要由CSDN通过智能技术生成

哈希算法在判定树同构方面的应用(上)

(一)需要掌握的前置知识:

(1)素数筛法:埃氏筛或者欧拉筛均可以。
以下为欧拉筛:

const int maxn=100100;
int p[maxn],cnt=0;
bool ha[maxn];
void Prime(void)
{
   
    ha[1]=true;
    for(int i=2;i<maxn;i++)
    {
   
        if(!ha[i]) p[++cnt]=i;
        for(int j=1;j<=cnt&&i*p[j]<maxn;j++)
        {
   
            ha[i*p[j]]=true;
            if(i%p[j]==0) break;
        }
    }
}

(2)一般的哈希知识。

(3)基本的树上 d f s dfs dfs 遍历整棵树。

(4)树上重心的求解:

树的重心: 找到一个点 x x x, 以点 x x x 为根时,其所有的子树中最大的子树节点数最少,那么这个点 x x x 就是这棵树的重心。(以重心为根时,最大子树最小)

性质:
(1)树中所有点到某个点的距离和中,到重心的距离和是最小的,如果有两个重心,他们的距离和一样。(这里树的边权都定义为 1 1 1
(2)把两棵树通过一条边相连,新的树的重心在原来两棵树重心的连线上。
(3)一棵树添加或者删除一个节点,树的重心最多只移动一条边的位置。
(4)一棵树最多有两个重心,且相邻。
(5)删除重心后所得的所有子树,节点数不超过原树的1/2。

其他说明:判定树同构有多种方法,且树同构的哈希也有多种方法,接下来仅介绍一种常用的哈希方法,其他的哈希方法类推即可。

(二)例题一:洛谷–P5043 【模板】树同构([BJOI2015]树的同构)

题目连接

题面截图:
在这里插入图片描述

题意:

给定 M M M 棵无根树,对于第 i i i 棵无根树寻找 1 − i 1-i 1i 中与第 i i i 棵无根树同构的最小的无根树的编号。

题解:

根据题意,我们很容易写出伪代码:

for(int i=1;i<=m;i++)
{
   
    for(int j=1;j<=i;j++)
    {
   
        if(第 i 棵树与第 j 棵树同构) //找到与第 i 棵树同构的树
        {
   
            printf("%d\n",j);
            break;
        }
    }
}

 
现在问题的关键转化为判断两棵无根树是否同构。
 
 
先来考虑问题的简化版:两个有根树如何判定是否同构。

类似于字符串的哈希,我们给树的每个节点附一个权值,记为 f [ x ] f[x] f[x]

我们设 f [ x ] = 1 + ∑ y ∈ s o n x f [ y ] ∗ p [ s i [ y ] ] f[x]=1+\sum\limits_{y\in son_x}f[y]*p[si[y]] f[x]=1+ysonxf[y]p[si[y]]。这里 f [ x ] f[x] f[x] 取自然溢出,即对 2 64 2^{64} 264 取模。

其中 y ∈ s o n x y\in son_x ysonx 表示在有根树中 y y y x x x 的儿子节点。 f [ y ] f[y] f[y] y y y f f f 函数。

p p p 数组是我们取前 k k k k > = s i [ r o o t ] k>=si[root] k>=si[root])个质数,再随机打乱后的数组。
随机打乱 p p p 数组。

random_shuffle(p+1,p+k+1);//k可以自己选定

s i [ x ] si[x] si[x] 表示 x x x 子树的大小。

那么如果判定两个有根树同构呢,我们认为 如果 f [ r o o t 1 ] = f [ r o o t 2 ] f[root1]=f[root2] f[root1]=f[root2],那么就可以认为两棵树同构。事实上虽然 f [ r o o t 1 ] = f [ r o o t 2 ] f[root1]=f[root2] f[

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值