luogu P5043 【模板】树同构 hash 最小表示法
LINK:模板 树同构
题目说的很迷 给了一棵有根树 但是重新标号 言外之意还是一棵无根树 然后要求判断是否重构。
由于时无根的 所以一个比较显然的想法暴力枚举根。
然后做树hash或者树的最小表示法。
前者做一次时n^2logn的 而后者则是严格的n^2logn的。
这样加上暴力枚举根就是n^3logn了。
最后我们将这些东西再sort一下和其他的树做对比 如果所有的都完全一致那么说明时同构的。
算法正确性 首先完全一样的树 再做树hash或者最小表示法时 得到的东西必然一样。
这个可以利用递归证明 经过再dfs中的sort可以发现变成唯一指定了。
考虑一个更优的做法 可以发现树的中心唯一/唯二 但是两个中心做hash却不尽相同。
可以对这两个点单独做 这样最后再对比即可。
这样就是n^2logn了。
最后 注意hash函数的设定 我第一次设的 竟然直接hash冲突了...
const int MAXN=55,cc0=19260817,cc1=114514;
int n,op,maxx;
int ha1[MAXN],ha2[MAXN],son[MAXN],sz[MAXN],s1,s2;
vector<int>g[MAXN][MAXN];
inline int dfs(int x,int fa)
{
ll h=cc0;
int q[MAXN],top=0;
for(ui i=0;i<g[op][x].size();++i)
{
int tn=g[op][x][i];
if(tn==fa)continue;
q[++top]=dfs(tn,x);
}
sort(q+1,q+1+top);
rep(1,top,i)h=(h*q[i])%mod;
return (h*P+cc1)%mod;
}
inline void get_root(int x,int fa)
{
sz[x]=1;son[x]=0;
for(ui i=0;i<g[op][x].size();++i)
{
int tn=g[op][x][i];
if(tn==fa)continue;
get_root(tn,x);
sz[x]+=sz[tn];
son[x]=max(son[x],sz[tn]);
}
son[x]=max(son[x],maxx-sz[x]);
if(son[s1]==son[x])s2=x;
if(son[s1]>son[x])s1=x,s2=0;
}
int main()
{
freopen("1.in","r",stdin);
get(n);son[0]=INF;
rep(1,n,i)
{
int get(x),root;
rep(1,x,j){int get(y);if(!y)root=j;else g[i][y].pb(j),g[i][j].pb(y);}
maxx=x;op=i;s1=s2=0;get_root(root,0);ha1[i]=dfs(s1,0);if(s2)ha2[i]=dfs(s2,0);else ha2[i]=-i;
}
rep(1,n,i)rep(1,n,j)if(ha1[i]==ha1[j]||ha1[i]==ha2[j]){put(j);break;}
return 0;
}
luogu P5043 【模板】树同构 hash 最小表示法的更多相关文章
- [luogu P3384] [模板]树链剖分
[luogu P3384] [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点 ...
- Luogu P3886 [JLOI2009]神秘的生物 最小表示法,轮廓线DP,插头DP,动态规划
亲手写掉的第一道最小表示法!哈哈哈太开心啦~ 不同于以往的几个插头\(dp\),这个题目的轮廓线是周围的一圈\(n\)个格子.而其所谓"插头"也变成了相邻格子的所属连通分量编号,并 ...
- POJ 1509 循环同构的最小表示法
题目大意: 给定一个字符串,可以把一段尾部接到头部,这样找到一个最小的字符串 方案一: 利用循环同构中找最小表示的方法来解决 论文参考http://wenku.baidu.com/view/438ca ...
- 『Tree nesting 树形状压dp 最小表示法』
Tree nesting (CF762F) Description 有两个树 S.T,问 S 中有多少个互不相同的连通子图与 T 同构.由于答案 可能会很大,请输出答案模 1000000007 后的值 ...
- luoguP3384 [模板]树链剖分
luogu P3384 [模板]树链剖分 题目 #include<iostream> #include<cstdlib> #include<cstdio> #inc ...
- 【KMP】【最小表示法】NCPC 2014 H clock pictures
题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1794 题目大意: 两个无刻度的钟面,每个上面有N根针(N<=200000),每个 ...
- Luogu 5043 【模板】树同构([BJOI2015]树的同构)
BZOJ 4337 简单记录一种树哈希的方法:以$x$为根的子树的哈希值为$\sum_{y \in son(x)}f_y*base_i$,$f_y$表示以$y$为根的树的哈希值,其中$i$表示$f_y ...
- POJ 1635 树的最小表示法/HASH
题目链接:http://poj.org/problem?id=1635 题意:给定两个由01组成的串,0代表远离根,1代表接近根.相当于每个串对应一个有根的树.然后让你判断2个串构成的树是否是同构的. ...
- [BZOJ4337][BJOI2015]树的同构(树的最小表示法)
4337: BJOI2015 树的同构 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1023 Solved: 436[Submit][Status ...
随机推荐
- requirejs之demo
具体的理论就不讲了,可以参考 http://www.ruanyifeng.com/blog/2012/10/javascript_module.html http://www.ruanyifeng.c ...
- SCOI 2010 连续攻击游戏(贪心,图论)
SCOI 2010 连续攻击游戏 solution 直接就硬刚 我愿称贪心为暴力 因为题目中要求一定从小到大贪心,那么当前点的下标有能够选取的较大点,那么它一定可以和前面的一个较小点连接,所以可以直接 ...
- P3261 [JLOI2015]城池攻占 题解
题目 小铭铭最近获得了一副新的桌游,游戏中需要用 \(m\) 个骑士攻占 \(n\) 个城池.这 \(n\) 个城池用 \(1\) 到 \(n\) 的整数表示.除 \(1\) 号城池外,城池 \(i\ ...
- Anbox补充:添加arm支持(失败!)
写在开头: 本人是一边操作一边写博文的,折腾一下午写到最后失败了不舍得删,还是发上来记录一下我的操作,希望能有高人指点或者给同学们一点启发.以下的内容仅做观看即可,若无必要就不必尝试了. 之前写了一篇 ...
- scala 数据结构(六):映射 Map
1 映射 Map-基本介绍 Scala中的Map介绍 1) Scala中的Map 和Java类似,也是一个散列表,它存储的内容也是键值对(key-value)映射,Scala中不可变的Map是有序的, ...
- 数据可视化之DAX篇(五) 使用PowerBI的这两个函数,灵活计算各种占比
https://zhuanlan.zhihu.com/p/57861350 计算个体占总体的比例是一个很常见的分析方式,它很简单,就是两个数字相除,但是当需要计算的维度.总体的范围发生动态变化时,如何 ...
- LeetCode第4题:寻找两个有序数组的中位数
double Solution::findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) ...
- EF实现简单的增删改查
1.在项目中添加ADO.NET实体数据模型: 2.接着根据提示配置数据库连接,配置完毕之后项目中生成了大致如下的内容(EF6.x): 其中TestData.tt中的Consumer,Stores是创建 ...
- 循序渐进VUE+Element 前端应用开发(16)--- 组织机构和角色管理模块的处理
在前面随笔<循序渐进VUE+Element 前端应用开发(15)--- 用户管理模块的处理>中介绍了用户管理模块的内容,包括用户列表的展示,各种查看.编辑.新增对话框的界面处理和后台数据处 ...
- SpringBoot 接收前端参数的几种方式
昨天和前端小伙伴在联调是碰到了参数接收不到的错误,我在postman上测试接口是正常的,但是与前端对接时就接受不到参数,请求方式都是get,但是问题就在于json 和 form-data 的区别!这 ...