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. Python——读取大文件(GB)

    最近处理文本文档时(文件约2GB大小),出现memoryError错误和文件读取太慢的问题,后来找到了两种比较快Large File Reading 的方法,本文将介绍这两种读取方法. Prelimi ...

  2. EOS基础全家桶(十五)智能合约进阶2

    简介 今天我们继续补充智能合约的进阶使用技巧,这次的主题是交易,合约内我们除了可以发起内联action的调用,很多使用还需要直接调用其他的合约action或者以交易的形式调用自身的action. 发起 ...

  3. vue重置data里的值

    this.$options.data() 这个可以获取原始的data值,this.$data 获取当前状态下的data,拷贝重新赋值一下就行了. Object.assign(this.$data, t ...

  4. java 面向对象(三十二):泛型一 泛型的理解

    1.泛型的概念所谓泛型,就是允许在定义类.接口时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型.这个类型参数将在使用时(例如,继承或实现这个接口,用这个类型声明变量.创建对象时确定 ...

  5. hihoCoder 1114 小Hi小Ho的惊天大作战:扫雷·一 最详细的解题报告

    题目来源:小Hi小Ho的惊天大作战:扫雷·一 解题思路:因为只要确定了第一个是否有地雷就可以推算出后面是否有地雷(要么为0,要么为1,如果不是这两个值就说明这个方案行不通),如果两种可能中有一种成功, ...

  6. Quartz.Net系列(十三):DateBuilder中的API详解

    1.DateOf.ToDayAt.TomorrowAt DateOf:指定年月日时分秒 public static DateTimeOffset DateOf(int hour, int minute ...

  7. tolua-ToLua#暖更新

    "重写"C#函数的Lua函数要访问C#类对象的没有wrap进Lua环境的私有数据成员.私有方法的时候,目前只能使用静态反射. 关于全Lua开发.全C#开发的问题.全Lua开发可能或 ...

  8. 【C#】WebService接受跨域请求及返回json数据

    问题概述 通过Web Service发布服务供客户端调用是一种非常简单.方便.快速的手段,并且服务发布后会有一个服务说明页面,直观明了,如图: 一般情况下,在web页面中的JavaScript中调用W ...

  9. CentOS7 64位下MySQL区分大小写

    在使用centos系统时,安装完MySQL数据库,创建完表之后,发现查询表操作时,是区分大小写的, 说以说在创建表之前,需要查看一下数据库是否区分大小写: 查看办法: lower_case_table ...

  10. webpack源码-loader的原理

    版本 webpack :"version": "3.12.0", webpack配置中的loaders配置是如何传递的 webpack/lib/NormalMo ...