https://www.hackerrank.com/contests/hourrank-21/challenges/tree-isomorphism

题目大意:

给出一棵树, 求有多少本质不同的子树。   N <= 19

下面给出我综合了网上一些做法后设计的hash函数(我不会证明碰撞概率)

判断两棵有根树是否相同:

将子树的Hash值从小到大排序, Hash(x) =  A * p xor Hash(son_1) mod q  * p  xor Hash(son_2) mod q ....  * p xor Hash(son_k) mod q * B mod q

判断两棵无根树是否相同:

找到重心 u, v(u 可能等于v, 即只有一个重心)  分别以它们为根求有根树Hash。不妨设 Hash(u) <= Hash(v)

Unrooted_Hash(x) = triple(n, u, v)  n为节点数。

对于本题, 只要暴力将每个子树的Unrooted_Hash 插入到set里就好了。

代码:

 //https://www.hackerrank.com/contests/hourrank-21/challenges/tree-isomorphism
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <set>
using namespace std; typedef long long ll; #define N 20
const int INF = << ;
const int P = , A = , B = ;
const ll mod = 1e12 + ;
const double pi = acos(-); vector<int> E[N], cone;
int size[N], cnt;
set<pair<int, pair<ll, ll> > > st; int DFS_SIZE(int x, int pre)
{
int res = ;
for (int i = ; i < E[x].size(); ++i)
{
int y = E[x][i];
if (y == pre) continue;
res += DFS_SIZE(y, x);
}
return size[x] = res;
} void Find_Cone(int x, int pre)
{
bool f = true;
for (int i = ; i < E[x].size(); ++i)
{
int y = E[x][i];
if (y == pre) continue;
Find_Cone(y, x);
if (size[y] > cnt / ) f = false;
}
if (cnt - size[x] > cnt / ) f = false;
if (f) cone.push_back(x);
} ll Hash(int x, int pre)
{
vector<ll> res;
for (int i = ; i < E[x].size(); ++i)
{
int y = E[x][i];
if (y == pre) continue;
res.push_back(Hash(y, x));
}
sort(res.begin(), res.end()); ll h = A;
for (int i = ; i < res.size(); ++i) h = (h * P ^ res[i]) % mod;
h = h * B % mod;
return h;
} int main()
{
//freopen("in.in", "r", stdin);
//freopen("out.out", "w", stdout); int n, x, y, a[], b[];
cin >> n;
for (int i = ; i < n - ; ++i) cin >> a[i] >> b[i], --a[i], --b[i];
for (int mask = ; mask < ( << n); ++mask)
{
for (int i = ; i < n; ++i) E[i].clear();
cone.clear(); cnt = ;
for (int i = ; i < n - ; ++i)
{
if ((mask & ( << a[i])) && (mask & ( << b[i])))
{
E[a[i]].push_back(b[i]);
E[b[i]].push_back(a[i]);
}
}
int root;
for (int i = ; i < n; ++i) if (mask & ( << i)) root = i, ++cnt;
if (DFS_SIZE(root, -) != cnt) continue; Find_Cone(root, -);
if (cone.size() == )
{
ll h = Hash(cone[], -);
st.insert(make_pair(cnt, make_pair(h, h)));
}
else
{
ll h1 = Hash(cone[], -), h2 = Hash(cone[], -);
if (h1 > h2) swap(h1, h2);
st.insert(make_pair(cnt, make_pair(h1, h2)));
}
}
printf("%d\n", (int)st.size());
return ;
}

Hourrank 21 Tree Isomorphism 树hash的更多相关文章

  1. 【HDU6647】Bracket Sequences on Tree(树Hash 树上Dp)

    题目链接 大意 给出一颗树,按下列方式生成一个括号序列. function dfs(int cur, int parent): print('(') for all nxt that cur is a ...

  2. CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划)

    CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划) Description 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的 ...

  3. 【数据结构】B-Tree, B+Tree, B*树介绍 转

    [数据结构]B-Tree, B+Tree, B*树介绍 [摘要] 最近在看Mysql的存储引擎中索引的优化,神马是索引,支持啥索引.全是浮云,目前Mysql的MyISAM和InnoDB都支持B-Tre ...

  4. B-Tree, B+Tree, B*树介绍

    [数据结构]B-Tree, B+Tree, B*树介绍 转   [数据结构]B-Tree, B+Tree, B*树介绍 [摘要] 最近在看Mysql的存储引擎中索引的优化,神马是索引,支持啥索引.全是 ...

  5. TZOJ 4292 Count the Trees(树hash)

    描述 A binary tree is a tree data structure in which each node has at most two child nodes, usually di ...

  6. 树hash

    判断树的同构,采用树hash的方式. 树hash定义在有根树上.判断无根树同构的时候,可以比较重心为根的hash值或者比较每个点为根的hash值. h[x]表示x为根的子树的hash,g[x]表示x为 ...

  7. POJ3237 Tree (树链剖分)

    通过打懒标记实现区间取反,和线段树基本操作都差不多. 本题还是一道边权化为点权的问题. 200行巨长代码: 1 #include<cstdio> 2 #include<cstring ...

  8. Mysql存储引擎之TokuDB以及它的数据结构Fractal tree(分形树)

    在目前的Mysql数据库中,使用最广泛的是innodb存储引擎.innodb确实是个很不错的存储引擎,就连高性能Mysql里都说了,如果不是有什么很特别的要求,innodb就是最好的选择.当然,这偏文 ...

  9. 页面设计--Tree目录树

    Tree目录树控件属性: 根据数据集合来配置相应的信息 加载模式有自动加载.自定加载 web中显示效果图:

随机推荐

  1. Hibernate开发环境搭建

    一.下载Hibernate包的下载 官网地址:http://hibernate.org/orm/ 下载版本:hibernate-release-4.3.11.Final 二.Hibernate jar ...

  2. 算法笔记_082:蓝桥杯练习 12-1三角形(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 为二维空间中的点设计一个结构体,在此基础上为三角形设计一个结构体.分别设计独立的函数计算三角形的周长.面积.中心和重心.输入三个点,输出这 ...

  3. Win7系统与它的Virtualbox中安装的Ubuntu14.04共享信息的几种方法

    虚拟机是每一个程序猿必备的工具.本文依据最新版VirtualBox用户手冊的提示,通过自己的亲自实践,给出了Win7系统与执行在当中的VirtualBox 5.0.2中的Ubuntu 14.04共享信 ...

  4. NET:Checkboxlist,Dropdownlist 加入ToolTip说明

    ToolTip属性: ToolTip 类 (System.Windows.Controls)‎ 表示创建弹出项的控件.该弹出项可显示界面中元素的相关信息.命名空间: System.Windows.Co ...

  5. Navicat Premium如何打开SQL文件.MDF和.LDF文件

    相信大家再装SQL Server时都会遇到一件很头疼的事情--装完SQL server之后发现没有启动程序.没有经验的会以为SQL SERVER安装失败了于是选择重装.可是呵呵,重装了4,5次还是一样 ...

  6. 分享几款流行的Java框架

    虽然Java一直被唱衰,但是直到现在Java软件开发也坚持霸主地位不动摇,毫无疑问,Java是目前最热门的编程语言之一,下面分享几个个人认为还不错的Java框架,以及各自的优缺点,希望能对大家有帮助. ...

  7. IT精英们不断上演的十大傻事(组图)

    http://fellow.51cto.com/art/200807/80475.htm

  8. php json_decode失败,返回null

    在使用json_decode之前,一定得保证字符串是utf-8编码,而执行json_decode失败的原因有很多,罗列如下: 1)编码不对: 2)字符串格式不对: 3)字符串格式对,但是有异常字符: ...

  9. 阿里云Ubuntu部署java web - 文件夹

    文件夹(点击章节标题阅读): 阿里云Ubuntu部署java web(1) - 系统配置         ssh链接server(使用终端远程链接)        加入用户        给用户赋予运 ...

  10. SQL Server 创建和使用索引

    创建索引: (1)在SQL Server Management Studio中,选择并右击要创建索引的表,从弹出菜单中选择“设计”,打开表设计器.右键单击表设计器,从弹出菜单中选择“索引/键”命令,打 ...