mark一下:

对于一个有根树,我们可以通过比较他们的括号序列的最小表示,如果他们的括号序列最小表示完全相等,那么他们同构

https://www.byvoid.com/blog/directed-tree-bracket-sequence

dfs进入某个子树用 '(' 表示,dfs结束用')'表示,这样就将一颗树转化成一个括号序列

只需将括号序列变成最小表示,就可以比较两棵树是否同构。但复杂度好像很高的样子...

回到树上来说,比较两棵子树的大小,可以先比较两个顶点的度,如果度相等,则递归比较子树。则可以看成是求一个最小的度序列

括号序列的另一个理解,就是poj上某道题。'('可以看成0,可以理解为向远离根节点的节点走,')'可以看成1,回溯,往回走。

于是比较两棵子树的大小,可以将两个01序列,看做为字符串,求最小表示。

不管是哪种序列,都可以作为树的最小表示。序列求出来,我们可以用 子序列排序+hash 得到一个新的序列,最后得到树的最小表示hash值。复杂度nlogn。

快速的算法可以参考 <Hash在信息学竞赛中的一类应用-杨弋>。

无根树可以通过一次拓扑排序,将整棵树收缩,最后只剩下一个点或者是两个点。枚举根即可。

贴一下UVA 12489 - Combating cancer 的代码,一脸水过的样子,不知道为什么用度序列hash连样例都过不了,01序列hash就过了。

hash函数找CJboy要的一个字符串hash的函数,不明觉厉~~

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
#include<iostream>using namespace std;#define For(i,forN) for(int i=0;i<forN;i++)
#define ForEdge(i,u) for(int i=head[u];i!=-1;i=edge[i].next)
#define sf  scanf
#define pf  printf
#define mp  make_pair#define _clr(x,y)   memset(x,(y),sizeof(x))typedef unsigned int UI ;
const int Maxn=21000,Mod=2081,hx=557,hy=131;
/*判断树的同构,用此hash函数:
*/
int head[Maxn],etot,Cc[Maxn];
int n;
UI  Hash[Maxn];
bool vis[Maxn];struct Edge
{int to,next;
}edge[Maxn*2];void init_edge()
{etot=0;_clr(head,-1);
}void add_edge(int u,int v)
{edge[etot].to=v;edge[etot].next=head[u];head[u]=etot++;
}void dfs(int u)
{vis[u]=true;vector < int > Ve;ForEdge(i,u){int v=edge[i].to;if(!vis[v]){dfs(v);Ve.push_back(Hash[v]);}}sort(Ve.begin(),Ve.end());  Ve.push_back(1);//可以看做字符')',或者1UI b = 378551 , a = 63689;Hash[u]=0;//可以看做字符'(',或者0
    For(i,Ve.size()){Hash[u]=Hash[u]*a+Ve[i];a*=b;}Hash[u]&=0x7FFFFFFF;
}int din[Maxn],stk[Maxn],top;
int ans[2][2];int main()
{while(~sf("%d",&n)){int tid[2]={0};for(int cas=0;cas<2;cas++){init_edge();int u,v;queue < int > q;_clr(din,0);for(int i=1;i<n;i++){sf("%d%d",&u,&v);din[u]++,din[v]++;add_edge(u,v);add_edge(v,u);}int last=n;_clr(vis,false);for(int i=1;i<n+1;i++){if(din[i]==1)   q.push(i),last--,vis[i]=true;}while(last!=0 && !q.empty()){u=q.front();    q.pop();    din[u]--;ForEdge(i,u){int v=edge[i].to;if(!vis[v]){din[v]--;if(din[v]==1)q.push(v),last--,vis[v]=true;}}}for(int i=1;i<=n;i++){if(din[i]==1){_clr(vis,false);    dfs(i);ans[cas][tid[cas]++]=Hash[i];if(tid[cas]>2)  while(1);}}}bool flag=false;for(int i=0;i<tid[0];i++)for(int j=0;j<tid[1];j++)if(ans[0][i] == ans[1][j])flag=true;if(flag)    puts("S");else    puts("N");}return 0;
}

转载于:https://www.cnblogs.com/CooCoo/p/3406186.html

树的最小表示法 UVA 12489 - Combating cancer相关推荐

  1. POJ 1635 Subway tree systems 树的Hash 或 树的最小表示法

    题目大意: 就是给出从树的中心开始的dfs序, 根据两个dfs序列判断两棵树是否同构 大致思路: 首先根据dfs一直是从树的中心开始的, 所以不用担心中心的问题, 用树的Hash的话当然可以做 另外一 ...

  2. 树的同构模板题(法1.最小表示法+法2.树哈希)

    树的同构 problem solution code solution code problem 模板题 solution Ⅰ. 最小表示法 将树转化为 0/10/10/1 括号序列:从根开始 dfs ...

  3. 无根树的同构:Hash最小表示法(bzoj 4337: BJOI2015 树的同构)

    这里的同构是指: 对于两棵树A, B,如果能通过重新标号使得两棵树完全相同,则称树A和B同构 Hash最小表示法步骤: ①暴力每个节点为根 ②对于当前根x,对树进行DFS ③DFS时对每个节点维护一个 ...

  4. UVA - 1314 Hidden Password(最小表示法)

    题目链接:点击查看 题目大意:给出一个字符串,求其最小表示法所代表的下标 题目分析:最小表示法的模板题,因为N给到了1e5,如果是正常的求最小值的话,时间复杂度是n*lens级别的,但最小表示法可以利 ...

  5. 2021秋季《数据结构》_EOJ 1063.树的双亲存储法(parent+child / parent)

    题目 前面介绍了树的链式存储结构,那么如何用顺序存储来存储一棵树呢?在顺序存储时,我们除了存储每个结点值外,还要存储树中结点与结点之间的逻辑关系(即双亲与孩子结点之间的关系).下面介绍树的双亲存储法. ...

  6. 字符串循环同构的最小表示法(转)

    循环字符串的最小表示法的问题可以这样描述: 对于一个字符串S,求S的循环的同构字符串S'中字典序最小的一个. 由于语言能力有限,还是用实际例子来解释比较容易: 设S=bcad,且S'是S的循环同构的串 ...

  7. 2018.07.17 洛谷P1368 工艺(最小表示法)

    传送门 好的一道最小表示法的裸板,感觉跑起来贼快(写博客时评测速度洛谷第二),这里简单讲讲最小表示法的实现. 首先我们将数组复制一遍接到原数组队尾,然后维护左右指针分别表示两个即将进行比较的字符串的头 ...

  8. poj1509最小表示法

    题意:       给你一个循环串,然后找到一个位置,使得从这个位置开始的整个串字典序最小. 思路:       最小表示法的建档应用,最小表示法很好理解,就点贪心的意思,一开始我们枚举两个起点i,j ...

  9. hdu3374最小表示法+KMP

    题意:       给你一个最长100W的串,然后让你找到最小同构子串,还有最大同构子串的下标,最小同构子串就是把字符串连接成一个环,然后选择一个地方断开,得到的一个ASCII最小的子串(求最大同理) ...

  10. 【运筹学】运输规划、表上作业法总结 ( 运输规划模型 | 运输规划变量个数 | 表上作业法 | 最小元素法 | 差额 Vogel 法 ★ | 闭回路法 ) ★★★

    文章目录 一.运输规划模型 1.产销平衡模型 2.产销不平衡模型 二.运输规划数学模型变量个数 三.表上作业法 四.表上作业法 : 求初始基可行解 1.最小元素法 2.差额法 ( Vogel ) 推荐 ...

最新文章

  1. .Net 转战 Android 4.4 日常笔记(7)--apk的打包与反编译
  2. SQL查询语句[0]
  3. Android之自定义View以及画一个时钟
  4. 基于MATLAB的LS-SVM实现方法以及SVM的一些知识点
  5. 渗透测试入门1之信息收集
  6. 第一个Eureka Service
  7. 嵌入式仿真用Qt播放器和录像机
  8. Android打开系统文件管理器
  9. 《成为乔布斯》读后感
  10. 用云服务器架设好服务器显示无法连接
  11. android 图片气泡,关于实现微信聊天气泡里显示图片解决方案
  12. 数学建模——公交调度优化
  13. Spring/Boot/Cloud系列知识(2)——代理模式
  14. 鸿蒙系统能玩魔兽世界吗,《魔兽世界》7.0配置公布:仍不放弃XP
  15. 坑,爱转换PDF转换器,熊猫办公
  16. 常用嵌入式操作系统介绍
  17. 几何画板Sketchpad5.0.6安装及PPT2016无缝使用
  18. Teams 如何创建一个 Channel
  19. 我的Electron个人学习笔记
  20. pytorch backward中的gradient参数实验

热门文章

  1. PS3主机数据完全一览及关键词解释
  2. oracle的floor用法,oracle ceil floor 函数的用法
  3. python中面向对象编程简称为_Python-面向对象编程
  4. 个人网站添加百度统计
  5. ”今日校园“App用户体验分析
  6. 贪吃蛇小游戏制作(3)
  7. 版本号规范,镜像版本SNAPSHOT,LATEST 和 RELEASE 版本
  8. 分享:MSDN visual studio 2010简体中文旗舰版,专业版下载(内置正版密钥)
  9. Python自动化操作word--批量替换word文档中的文字
  10. 美国MAK Technoligies介绍