Hourrank 21 Tree Isomorphism 树hash
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的更多相关文章
- 【HDU6647】Bracket Sequences on Tree(树Hash 树上Dp)
题目链接 大意 给出一颗树,按下列方式生成一个括号序列. function dfs(int cur, int parent): print('(') for all nxt that cur is a ...
- CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划)
CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划) Description 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的 ...
- 【数据结构】B-Tree, B+Tree, B*树介绍 转
[数据结构]B-Tree, B+Tree, B*树介绍 [摘要] 最近在看Mysql的存储引擎中索引的优化,神马是索引,支持啥索引.全是浮云,目前Mysql的MyISAM和InnoDB都支持B-Tre ...
- B-Tree, B+Tree, B*树介绍
[数据结构]B-Tree, B+Tree, B*树介绍 转 [数据结构]B-Tree, B+Tree, B*树介绍 [摘要] 最近在看Mysql的存储引擎中索引的优化,神马是索引,支持啥索引.全是 ...
- 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 ...
- 树hash
判断树的同构,采用树hash的方式. 树hash定义在有根树上.判断无根树同构的时候,可以比较重心为根的hash值或者比较每个点为根的hash值. h[x]表示x为根的子树的hash,g[x]表示x为 ...
- POJ3237 Tree (树链剖分)
通过打懒标记实现区间取反,和线段树基本操作都差不多. 本题还是一道边权化为点权的问题. 200行巨长代码: 1 #include<cstdio> 2 #include<cstring ...
- Mysql存储引擎之TokuDB以及它的数据结构Fractal tree(分形树)
在目前的Mysql数据库中,使用最广泛的是innodb存储引擎.innodb确实是个很不错的存储引擎,就连高性能Mysql里都说了,如果不是有什么很特别的要求,innodb就是最好的选择.当然,这偏文 ...
- 页面设计--Tree目录树
Tree目录树控件属性: 根据数据集合来配置相应的信息 加载模式有自动加载.自定加载 web中显示效果图:
随机推荐
- Android开发--用户定位服务--UserLocation
Android开发--用户定位服务--UserLocation 2013-01-28 08:32:26 我来说两句 作者:BruceZhang 收藏 我要投稿 [java] & ...
- Afinal的jar包进行代码混淆出错
今天用到了代码混淆,混淆过后APP不能够运行,老报错,由于项目中只用了Afinal的第三方库,于是按照网上给出的答案为了不混淆Afinal的jar包,在配置文件中写入了下面的语句: -libraryj ...
- Tomcat源代码解析系列
学web也有一段时间了.为了从底层了解web应用在Tomcat中的执行,决定看一下Tomcat的源代码參见<How Tomcat works> 和大牛博客.对大体架构有了一定的了解, ...
- Redis使用经验
首先,缓存的对象有三种: 1:数据库中单条的的数据(以表名跟id作为key永久保存到Redis),在有更新的地方都要更新缓存(不适用于需要经常更新的数据): 2:对于一些不分页,不需要实时(需要多表查 ...
- hudson status
http://sin90lzc.iteye.com/blog/1072123在eclipse上显示hudson构建状态 update site:http://eclipse-plugin-potpou ...
- excel合并单元格
最简单的: =A1&B1&C1 在C14单元格中输入公式:=CONCATENATE(A14,"@",B14,".com"),确认后,即可将A14 ...
- checkbox 全选操作
<html> <head></head> <body> <div id="places"> <input type ...
- List分组迭代器 C#--深入理解类型
List分组迭代器 说明: 针对长度较大的List对象,可以分组批量进行处理, 如:长度为1000的List对象,可分为10组,每组100条,对数据进行业务逻辑处理... Source /**** ...
- C# 异或校验算法
C# 的异或校验算法 直接上代码 public partial class FormCRC : Form { public FormCRC() { InitializeComponent(); } p ...
- 浅析C#中 ConcurrentDictionary的实现
简单画了一张图 (灵魂画手 →_→) 如图 ConcurrentDictionary 其中有个tables 对象主要存储,而这个 tables 是一个 很多区块的 数组 ,每个区块 又是一个node的 ...