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. Xshell连接mysql数据库乱码问题解决思路总结

    乱码问题一直是一件让人头疼的事情,乱码就是编码格式不统一产生的,下面将一些常见的解决思路整理: 先Xshell连接上数据库,查看数据的编码格式: 一般需要看这么几个地方(附修改命令): 1.数据库的编 ...

  2. js实现全选,全不选,反选

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. es6 对象简化写法-函数

    表达式还可以用于定义方法名. let obj = { ['h' + 'ello']() { return 'hi'; } }; obj.hello() // hi

  4. (二)Solr——Solr界面介绍

    1. Dashboard 仪表盘,显示了该Solr实例开始启动运行的时间.版本.系统资源.jvm等信息. 2. Logging Solr运行日志信息 3. Cloud Cloud即SolrCloud, ...

  5. zabbix触发的多条件判断表达式

    2 Trigger expression   Overview The expressions used in triggers are very flexible. You can use them ...

  6. C++开源库大全(转)

    程序员要站在巨人的肩膀上,C++拥有丰富的开源库,这里包括:标准库.Web应用框架.人工智能.数据库.图片处理.机器学习.日志.代码分析等. 标准库 C++ Standard Library:是一系列 ...

  7. CodeSmith单表生成实体模板与生成多表实体模板

    生成单实体模板: <%@ Template Language="C#" TargetLanguage="C#" %> <%@ Assembly ...

  8. [css]margin-top重叠

  9. iOS直播-基于RTMP的视频推送

    iOS直播-基于RTMP的视频推送 所谓的视频推送就是把摄像头和麦克风捕获到视频和音频推送到直播服务器上.我们这里使用推送协议是RTMP协议. 扩展:腾讯直播平台,阿里直播平台,百度直播平台提供均为R ...

  10. html-文本处理

    文本处理-相关操作: <!-- 申明为html5版本 --> <!DOCTYPE html> <html> <head> <title>文本 ...