模板口胡:树同构
太菜了,不会 AHU。
这里介绍树哈希算法。
树哈希
有根树哈希
我们怎么快速判断两棵树是否同构呢?使用树哈希!
我们把每棵同构树用一个哈希值代表。
也就是说,两棵同构的树用用同一个哈希值代替。
我们可以理解为,每个哈希值都映射着唯一的树。
那么怎么计算一棵树的哈希值呢?我们令根节点代表的是整棵树的哈希值。
所以当前节点的哈希值可以通过子树哈希得到。
我们知道,只要所有根节点的子树相同,那么这就是同构的树。
由于子树之间不存在顺序,所以我们考虑和哈希。
在这一步,前人经过大量挖掘,终于研制出一种很难卡的哈希算法:
定义转换函数 \(g(x)\) 每个相同 的 \(x\) 都会产出一个唯一的 \(x\)
产出唯一通过异或运算即可,采用自然溢出最好。
所以,我们得到每个节点的哈希计算通式:
\[f(x)=c+\sum\limits_{v\in E_u} g(f(v))
\]
一般 \(c=1\) 。
我觉得这是正确的,因为 \(g(x)\) 可以通过人类智慧构造出 114514 种写法。
板子是能过的。
无根树哈希
上面说的所有都是有根树。
对于无根树,我们有两种方案:
- 取重心为根,如果有两个,则都计算,取值小的那个。
- 随意取根,对于整棵树做一次换根 dp ,然后取值最小的。
时间复杂度都是 \(O(n)\) 的,一般来说,第二种拓展性更好。