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 最小表示法的更多相关文章

  1. [luogu P3384] [模板]树链剖分

    [luogu P3384] [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点 ...

  2. Luogu P3886 [JLOI2009]神秘的生物 最小表示法,轮廓线DP,插头DP,动态规划

    亲手写掉的第一道最小表示法!哈哈哈太开心啦~ 不同于以往的几个插头\(dp\),这个题目的轮廓线是周围的一圈\(n\)个格子.而其所谓"插头"也变成了相邻格子的所属连通分量编号,并 ...

  3. POJ 1509 循环同构的最小表示法

    题目大意: 给定一个字符串,可以把一段尾部接到头部,这样找到一个最小的字符串 方案一: 利用循环同构中找最小表示的方法来解决 论文参考http://wenku.baidu.com/view/438ca ...

  4. 『Tree nesting 树形状压dp 最小表示法』

    Tree nesting (CF762F) Description 有两个树 S.T,问 S 中有多少个互不相同的连通子图与 T 同构.由于答案 可能会很大,请输出答案模 1000000007 后的值 ...

  5. luoguP3384 [模板]树链剖分

    luogu P3384 [模板]树链剖分 题目 #include<iostream> #include<cstdlib> #include<cstdio> #inc ...

  6. 【KMP】【最小表示法】NCPC 2014 H clock pictures

    题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1794 题目大意: 两个无刻度的钟面,每个上面有N根针(N<=200000),每个 ...

  7. Luogu 5043 【模板】树同构([BJOI2015]树的同构)

    BZOJ 4337 简单记录一种树哈希的方法:以$x$为根的子树的哈希值为$\sum_{y \in son(x)}f_y*base_i$,$f_y$表示以$y$为根的树的哈希值,其中$i$表示$f_y ...

  8. POJ 1635 树的最小表示法/HASH

    题目链接:http://poj.org/problem?id=1635 题意:给定两个由01组成的串,0代表远离根,1代表接近根.相当于每个串对应一个有根的树.然后让你判断2个串构成的树是否是同构的. ...

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

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

随机推荐

  1. RESTful API 规范(一)

    一,简介 DRF 即Django rest framework 二,rest 规范 1 协议 API 与用户通信,总是使用https协议 2 域名 1) 应尽量将API 部署在域名下(这种情况会存在跨 ...

  2. SCOI 2016 萌萌哒

    SCOI 2016 萌萌哒 solution 有点线段树的味道,但是并不是用线段树来做,而是用到另外一个区间修改和查询的利器--ST表 我们可以将一个点拆成\(logN\)个点,分别代表从点\(i\) ...

  3. 最新Spark入门篇

    一.Spark简介 1.什么是Spark Apache Spark是一种快速的集群计算技术,基于Hadoop MapReduce技术,扩展了MapReduce模型,主要特性是在内存中集群计算,速度更快 ...

  4. nuxt的使用中碰到的问题

    使用npm run generate生成静态页面部署 如果不是部署在域名的根目录下,则需要在nuxt.config.js中添加 // nuxt.config.js export default { r ...

  5. python 爬虫由于网络或代理不能用导致的问题处理方法

    平时在爬取某些网页的时候,可能是由于网络不好或者代理池中的代理不能用导致请求失败.此时有们需要重复多次去请求,python中有现成的,相应的包供我们使用: 我们可以利用retry模块进行多次请求,如果 ...

  6. Python-01矩阵、数组和列表等的总结

    python的基础知识总结 使用到了numpy库,所以第一步需要 import numpy as np 1.创建矩阵 1.1一般矩阵的创建 创建一个二维的矩阵,并使用ndim.shape.size分别 ...

  7. 数据可视化之powerBI基础(二十)Power BI度量值和新建表,有什么异同?

    https://zhuanlan.zhihu.com/p/101812525 ​PowerBI中,有三个地方可以使用DAX,分别是度量值.新建列和新建表,这三个功能并成一排摆放在这里,如图所示, 之前 ...

  8. Django之 Models组件

    本节内容 路由系统 models模型 admin views视图 template模板 引子 讲django的models之前, 先来想一想, 让你通过django操作数据库,你怎么做? 做苦思冥想, ...

  9. JavaScript 基础 学习(三)

    JavaScript 基础 学习(三) 事件三要素 ​ 1.事件源: 绑定在谁身上的事件(和谁约定好) ​ 2.事件类型: 绑定一个什么事件 ​ 3.事件处理函数: 当行为发生的时候,要执行哪一个函数 ...

  10. 【翻译】.NET 5中的性能改进

    [翻译].NET 5中的性能改进 在.NET Core之前的版本中,其实已经在博客中介绍了在该版本中发现的重大性能改进. 从.NET Core 2.0到.NET Core 2.1到.NET Core ...