题目链接

有根树的哈希

离散数学中对树哈希的描述在这里。大家可以看看。

判断有根树是否同构,可以考虑将有根树编码。而编码过程中,要求保留树形态的特征,同时忽略子树顺序的不同。先来看一看这个方法:

不妨令一棵树的编码是个字符串\(T\)。

对于一个点\(u\),先求出\(u\)所有\(son_u\)的编码\(f_{son_u}\),然后将这些编码按字典序从小到大排序得到\(g_{1\cdots k}\)。那么\(f_u="0"+\sum\limits g_i+"1"\)。

令\(T\)的编码为根节点的编码。

通过解码的方式可以验证这个算法的正确性。

这个只是树的编码,并不算是树的哈希。这个编码保证了正确性。而实际上,我们应用的时候,通常不会,也不允许这样做(时间空间都吃不消)。我们通常会采用数值的操作和取模的方法。而实际上,这个数值的操作要尽可能满足保留树形态的特征,同时忽略子树顺序的不同。加法、异或、排序等都是可以的。

树哈希的方法非常多,OIwiki上有三种常见的做法

无根树的哈希

一般的,通过选定根将无根树转成有根树,从而实现无根树的编码。而根一般选定为数的中心。如果有两个中心,就选定编码较小中心为根。对于哈希也是差不多的道理。

对于这道题,由于数据范围十分小,所以直接暴力编码,map判重即可。

#include <bits/stdc++.h>
using namespace std; const int Maxn = 60;
struct edge {
int To, Next;
edge() {}
edge( int _To, int _Next ) : To( _To ), Next( _Next ) {}
};
int Start[ Maxn ], Used;
edge Edge[ Maxn << 1 ];
inline void AddEdge( int x, int y ) {
Edge[ ++Used ] = edge( y, Start[ x ] );
Start[ x ] = Used;
return;
} map< string, int > Map;
string A[ Maxn ], B[ Maxn ], S;
int n, m, T[ Maxn ];
int Cnt, Rt[ Maxn ]; int Dfs1( int u, int Fa ) {
int Size = 1, IsR = 1;
for( int t = Start[ u ]; t; t = Edge[ t ].Next ) {
int v = Edge[ t ].To;
if( v == Fa ) continue;
int T = Dfs1( v, u );
if( T > n / 2 ) IsR = 0;
Size += T;
}
if( n - Size > n / 2 ) IsR = 0;
if( IsR ) Rt[ ++Cnt ] = u;
return Size;
} void Cal( int u, int Fa ) {
for( int t = Start[ u ]; t; t = Edge[ t ].Next ) {
int v = Edge[ t ].To;
if( v == Fa ) continue;
Cal( v, u );
}
A[ u ] = "0";
int Cnt = 0;
for( int t = Start[ u ]; t; t = Edge[ t ].Next ) {
int v = Edge[ t ].To;
if( v == Fa ) continue;
B[ ++Cnt ] = A[ v ];
}
sort( B + 1, B + Cnt + 1 );
for( int i = 1; i <= Cnt; ++i )
A[ u ] = A[ u ] + B[ i ];
A[ u ] = A[ u ] + "1";
return;
} int main() {
scanf( "%d", &m );
for( int i = 1; i <= m; ++i ) {
memset( Start, 0, sizeof( Start ) );
Used = 0;
scanf( "%d", &n );
for( int j = 1; j <= n; ++j ) {
int x;
scanf( "%d", &x );
if( x == 0 ) continue;
AddEdge( x, j );
AddEdge( j, x );
}
Cnt = 0;
Dfs1( 1, 0 );
Cal( Rt[ 1 ], 0 );
S = A[ Rt[ 1 ] ];
for( int j = 2; j <= Cnt; ++j ) {
Cal( Rt[ j ], 0 );
if( A[ Rt[ j ] ] < S )
S = A[ Rt[ j ] ];
}
if( Map.find( S ) == Map.end() ) Map[ S ] = i;
printf( "%d\n", Map[ S ] );
}
return 0;
}

[BJOI2015]树的同构 && 树哈希教程的更多相关文章

  1. bzoj4337: BJOI2015 树的同构 树哈希判同构

    题目链接 bzoj4337: BJOI2015 树的同构 题解 树哈希的一种方法 对于每各节点的哈希值为hash[x] = hash[sonk[x]] * p[k]; p为素数表 代码 #includ ...

  2. BZOJ 4337: BJOI2015 树的同构 树hash

    4337: BJOI2015 树的同构 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4337 Description 树是一种很常见的数 ...

  3. BZOJ4337:[BJOI2015]树的同构(树hash)

    Description 树是一种很常见的数据结构. 我们把N个点,N-1条边的连通无向图称为树. 若将某个点作为根,从根开始遍历,则其它的点都有一个前驱,这个树就成为有根树. 对于两个树T1和T2,如 ...

  4. [BZOJ4337][BJOI2015]树的同构(树的最小表示法)

    4337: BJOI2015 树的同构 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1023  Solved: 436[Submit][Status ...

  5. 【BZOJ4474】isomorphism(树的同构,哈希)

    题意:一个无向树的度数为 2的结点称为假结点,其它结点称为真结点.一个无向树的简化树其结点由原树的全体真结点组成,两个真结点之间有边当且仅当它们在原树中有边,或者在原树中有一条联结这两个结点的路,其中 ...

  6. BZOJ.4337.[BJOI2015]树的同构(树哈希)

    BZOJ 洛谷 \(Description\) 给定\(n\)棵无根树.对每棵树,输出与它同构的树的最小编号. \(n及每棵树的点数\leq 50\). \(Solution\) 对于一棵无根树,它的 ...

  7. BZOJ4337 树的同构 (树哈希)(未完成)

    样例迷,没过 交了30pts #include <cstdio> #include <iostream> #include <cstring> #include & ...

  8. [BJOI2015]树的同构

    嘟嘟嘟 判断树的同构的方法就是树上哈希. 如果树是一棵有根树,那么只要从根节点出发dfs,每一个节点的哈希值等于按传统方式算出来的子树的哈希值的结果.需要注意的是,算完子树的哈希值后要先排序再加起来, ...

  9. 【BZOJ4337】BJOI2015 树的同构 括号序列

    [BZOJ4337]BJOI2015 树的同构 Description 树是一种很常见的数据结构. 我们把N个点,N-1条边的连通无向图称为树. 若将某个点作为根,从根开始遍历,则其它的点都有一个前驱 ...

随机推荐

  1. hype-v上centos7部署高可用kubernetes集群实践

    概述 在上一篇中已经实践了 非高可用的bubernetes集群的实践 普通的k8s集群当work node 故障时是高可用的,但是master node故障时将会发生灾难,因为k8s api serv ...

  2. nodejs和npm

    Node.js安装及环境配置之Windows篇:https://www.cnblogs.com/liuqiyun/p/8133904.html 淘宝NPM镜像:https://npm.taobao.o ...

  3. nop4.1学习ServiceCollectionExtensions(一)

    从入口进去,读取系统appsetting.jion的配置文件: 单例实例化配置数据,全局调用 注入HttpContextAccessor ASP.NET Core中提供了一个IHttpContextA ...

  4. 动画方案 Lottie 学习(二)之实战

    代码 $('.success-info-title').append('<p class="normal_finish" id="normal_finish_ani ...

  5. 使用SSH连接AWS服务器

    使用SSH连接AWS服务器 一直有一台AWS云主机,但是之前在Windows平台都是使用Xshell连接的,换到Ubuntu环境之后还没有试,昨天试了一下,终于使用SSH连接成功了,这里记录一下步骤: ...

  6. asp.net Core 2.0 MVC为Controller或Action添加定制特性实现登录验证

    前言:最近在倒腾 微软的新平台 asp.net Core 2.0,在这个过程中有些东西还是存在差异.下面是我在学习过程的一点笔记.有不妥之处,望各位大虾指正! 一.先创建一个控制器继承于Control ...

  7. netty的断线重连问题

    手里的这个项目需要作为客户端,不断的接收服务端发来的数据,用的netty框架,但是一直存在一个问题,就是断线重连问题. 什么是断线重连呢? 就是我们这个客户端要保证一直与服务端保持连接,这样客户端才能 ...

  8. 使用WSGI创建REST接口

    问题 你想使用一个简单的REST接口通过网络远程控制或访问你的应用程序,但是你又不想自己去安装一个完整的web框架. 解决方案 构建一个REST风格的接口最简单的方法是创建一个基于WSGI标准(PEP ...

  9. go语言入门(2)数据类型

    1,命名 Go语言中的函数名.变量名.常量名.类型名.语句标号和包名等所有的命名,都遵循一个简单的命名规则:一个名字必须以一个字母(Unicode字母)或下划线开头,后面可以跟任意数量的字母.数字或下 ...

  10. C#字符串和16进制字符串之间的转换

    将字符串编码成 16进制 字符串表示: using System;using System.Collections.Generic;using System.Linq;using System.Tex ...