树的最小表示法 UVA 12489 - Combating cancer
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相关推荐
- POJ 1635 Subway tree systems 树的Hash 或 树的最小表示法
题目大意: 就是给出从树的中心开始的dfs序, 根据两个dfs序列判断两棵树是否同构 大致思路: 首先根据dfs一直是从树的中心开始的, 所以不用担心中心的问题, 用树的Hash的话当然可以做 另外一 ...
- 树的同构模板题(法1.最小表示法+法2.树哈希)
树的同构 problem solution code solution code problem 模板题 solution Ⅰ. 最小表示法 将树转化为 0/10/10/1 括号序列:从根开始 dfs ...
- 无根树的同构:Hash最小表示法(bzoj 4337: BJOI2015 树的同构)
这里的同构是指: 对于两棵树A, B,如果能通过重新标号使得两棵树完全相同,则称树A和B同构 Hash最小表示法步骤: ①暴力每个节点为根 ②对于当前根x,对树进行DFS ③DFS时对每个节点维护一个 ...
- UVA - 1314 Hidden Password(最小表示法)
题目链接:点击查看 题目大意:给出一个字符串,求其最小表示法所代表的下标 题目分析:最小表示法的模板题,因为N给到了1e5,如果是正常的求最小值的话,时间复杂度是n*lens级别的,但最小表示法可以利 ...
- 2021秋季《数据结构》_EOJ 1063.树的双亲存储法(parent+child / parent)
题目 前面介绍了树的链式存储结构,那么如何用顺序存储来存储一棵树呢?在顺序存储时,我们除了存储每个结点值外,还要存储树中结点与结点之间的逻辑关系(即双亲与孩子结点之间的关系).下面介绍树的双亲存储法. ...
- 字符串循环同构的最小表示法(转)
循环字符串的最小表示法的问题可以这样描述: 对于一个字符串S,求S的循环的同构字符串S'中字典序最小的一个. 由于语言能力有限,还是用实际例子来解释比较容易: 设S=bcad,且S'是S的循环同构的串 ...
- 2018.07.17 洛谷P1368 工艺(最小表示法)
传送门 好的一道最小表示法的裸板,感觉跑起来贼快(写博客时评测速度洛谷第二),这里简单讲讲最小表示法的实现. 首先我们将数组复制一遍接到原数组队尾,然后维护左右指针分别表示两个即将进行比较的字符串的头 ...
- poj1509最小表示法
题意: 给你一个循环串,然后找到一个位置,使得从这个位置开始的整个串字典序最小. 思路: 最小表示法的建档应用,最小表示法很好理解,就点贪心的意思,一开始我们枚举两个起点i,j ...
- hdu3374最小表示法+KMP
题意: 给你一个最长100W的串,然后让你找到最小同构子串,还有最大同构子串的下标,最小同构子串就是把字符串连接成一个环,然后选择一个地方断开,得到的一个ASCII最小的子串(求最大同理) ...
- 【运筹学】运输规划、表上作业法总结 ( 运输规划模型 | 运输规划变量个数 | 表上作业法 | 最小元素法 | 差额 Vogel 法 ★ | 闭回路法 ) ★★★
文章目录 一.运输规划模型 1.产销平衡模型 2.产销不平衡模型 二.运输规划数学模型变量个数 三.表上作业法 四.表上作业法 : 求初始基可行解 1.最小元素法 2.差额法 ( Vogel ) 推荐 ...
最新文章
- .Net 转战 Android 4.4 日常笔记(7)--apk的打包与反编译
- SQL查询语句[0]
- Android之自定义View以及画一个时钟
- 基于MATLAB的LS-SVM实现方法以及SVM的一些知识点
- 渗透测试入门1之信息收集
- 第一个Eureka Service
- 嵌入式仿真用Qt播放器和录像机
- Android打开系统文件管理器
- 《成为乔布斯》读后感
- 用云服务器架设好服务器显示无法连接
- android 图片气泡,关于实现微信聊天气泡里显示图片解决方案
- 数学建模——公交调度优化
- Spring/Boot/Cloud系列知识(2)——代理模式
- 鸿蒙系统能玩魔兽世界吗,《魔兽世界》7.0配置公布:仍不放弃XP
- 坑,爱转换PDF转换器,熊猫办公
- 常用嵌入式操作系统介绍
- 几何画板Sketchpad5.0.6安装及PPT2016无缝使用
- Teams 如何创建一个 Channel
- 我的Electron个人学习笔记
- pytorch backward中的gradient参数实验
热门文章
- PS3主机数据完全一览及关键词解释
- oracle的floor用法,oracle ceil floor 函数的用法
- python中面向对象编程简称为_Python-面向对象编程
- 个人网站添加百度统计
- ”今日校园“App用户体验分析
- 贪吃蛇小游戏制作(3)
- 版本号规范,镜像版本SNAPSHOT,LATEST 和 RELEASE 版本
- 分享:MSDN visual studio 2010简体中文旗舰版,专业版下载(内置正版密钥)
- Python自动化操作word--批量替换word文档中的文字
- 美国MAK Technoligies介绍