题目链接:http://poj.org/problem?id=1635

题意:给定两个由01组成的串,0代表远离根,1代表接近根。相当于每个串对应一个有根的树。然后让你判断2个串构成的树是否是同构的。

思路:首先根据01串构造出树,然后求树的最小表示法判断同构。 详情参照:https://www.byvoid.com/blog/directed-tree-bracket-sequence/

  1. #define _CRT_SECURE_NO_DEPRECATE
  2. #include<iostream>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<string>
  6. #include<cstdio>
  7. #include<vector>
  8. using namespace std;
  9. typedef long long int LL;
  10. const int MAXN=+;
  11. int fa[MAXN];
  12. char strA[MAXN],strB[MAXN];
  13. vector<int>treeA[MAXN],treeB[MAXN];
  14. void build(char *s,vector<int>tree[MAXN]){
  15. int hashNum=,now=,len=strlen(s);
  16. for(int i=;i<MAXN;i++){
  17. tree[i].clear();
  18. }
  19. for(int i=;i<len;i++){
  20. if(s[i]==''){
  21. fa[hashNum]=now;
  22. tree[now].push_back(hashNum);
  23. now=hashNum++;
  24. }
  25. else{
  26. now=fa[now];
  27. }
  28. }
  29. }
  30. string dfs(int now,vector<int>tree[MAXN]){
  31. vector<string>HashC;
  32. for(int i=;i<tree[now].size();i++){
  33. HashC.push_back(dfs(tree[now][i],tree));
  34. }
  35. string Hash="(";
  36. sort(HashC.begin(),HashC.end());
  37. for(int i=;i<HashC.size();i++){
  38. Hash+=HashC[i];
  39. }
  40. Hash+=")";
  41. return Hash;
  42. }
  43. int main()
  44. {
  45. int t;
  46. scanf("%d",&t);
  47. while(t--){
  48. scanf("%s",strA); scanf("%s",strB);
  49. memset(fa,,sizeof(fa));build(strA,treeA);
  50. memset(fa,,sizeof(fa));build(strB,treeB);
  51. if(dfs(,treeA)==dfs(,treeB)){
  52. printf("same\n");
  53. }
  54. else{
  55. printf("different\n");
  56. }
  57. }
  58. return ;
  59. }

思路2:HASH,思路参照:集训队论文:杨弋《Hash在信息学竞赛中的一类应用》

题目卡的比较死。 参数不好拿捏。最好进行Double HASH比较保险

  1. #define _CRT_SECURE_NO_DEPRECATE
  2. #include<iostream>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<string>
  6. #include<cstdio>
  7. #include<vector>
  8. using namespace std;
  9. typedef long long int LL;
  10. typedef unsigned int uint;
  11. const int MAXN=+;
  12. const int MODF=1e9+;
  13. const int MODS=1e9+;
  14. int fa[MAXN],HF[MAXN],HS[MAXN];
  15. char strA[MAXN],strB[MAXN];
  16. vector<int>treeA[MAXN],treeB[MAXN];
  17. void build(char *s,vector<int>tree[MAXN]){
  18. int hashNum=,now=,len=strlen(s);
  19. for(int i=;i<MAXN;i++){
  20. tree[i].clear();
  21. }
  22. for(int i=;i<len;i++){
  23. if(s[i]==''){
  24. fa[hashNum]=now;
  25. tree[now].push_back(hashNum);
  26. now=hashNum++;
  27. }
  28. else{
  29. now=fa[now];
  30. }
  31. }
  32. }
  33. pair<int,int> dfs(int now,vector<int>tree[MAXN]){
  34. int HashNumF=,HashNumS=;
  35. vector<pair<int,int> >HashC;
  36. for(int i=;i<tree[now].size();i++){
  37. HashC.push_back(dfs(tree[now][i],tree));
  38. }
  39. sort(HashC.begin(),HashC.end());
  40. for(int i=;i<HashC.size();i++){
  41. HashNumF=((HashNumF^HashC[i].first)*HF[i])%MODF;
  42. HashNumS=((HashNumS^HashC[i].second)*HS[i])%MODS;
  43. }
  44. return make_pair(HashNumF%MODF,HashNumS%MODS);
  45. }
  46. int main()
  47. {
  48. for(int i=;i<MAXN;i++){
  49. HF[i]=rand()%MODF;
  50. HS[i]=rand()%MODS;
  51. }
  52. int t;
  53. scanf("%d",&t);
  54. while(t--){
  55. scanf("%s",strA); scanf("%s",strB);
  56. memset(fa,,sizeof(fa));build(strA,treeA);
  57. memset(fa,,sizeof(fa));build(strB,treeB);
  58. pair<int,int>TA=dfs(,treeA);
  59. pair<int,int>TB=dfs(,treeB);
  60. if(TA.first==TB.first&&TA.second==TB.second){
  61. printf("same\n");
  62. }
  63. else{
  64. printf("different\n");
  65. }
  66. }
  67. return ;
  68. }

POJ 1635 树的最小表示法/HASH的更多相关文章

  1. POJ 1635 树的最小表示法

    题目大意: 用一堆01字符串表示在树上走动的路径,0表示往前走,1表示往回走,问两种路径方式下形成的树是不是相同的树 我们可以利用递归的方法用hash字符串表示每一棵子树,然后将所有子树按照字典序排序 ...

  2. POJ1635 Subway tree systems ——(判断树的同构,树的最小表示法)

    给两棵有根树,判断是否同构.因为同构的树的最小表示法唯一,那么用最小表示法表示这两棵树,即可判断同构.顺便如果是无根树的话可以通过选出重心以后套用之前的方法. AC代码如下: #include < ...

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

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

  4. HDU 1954 Subway tree systems (树的最小表示法)

    题意:用一个字符串表示树,0代表向下走,1代表往回走,求两棵树是否同构. 分析:同构的树经过最小表示会转化成两个相等的串. 方法:递归寻找每一棵子树,将根节点相同的子树的字符串按字典序排列,递归回去即 ...

  5. UVA 719 / POJ 1509 Glass Beads (最小表示法/后缀自动机)

    题目大意: 给出一个长度为N的字符串,求其字典序最小的循环同构. N<=10W. 算法讨论: 算法一.最小表示法.定义题. 算法二.后缀自动机. Codes: #include <iost ...

  6. 1282 时钟(最小表示法+hash)

    1282 时钟 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 有N个时钟,每个时钟有M个指针,P个刻度.时钟是圆形的,P个刻度均分整 ...

  7. POJ 1635 Subway tree systems (树的最小表示法)

    题意:一串01序列,从一个点开始,0表示去下一个点,1表示回到上一个点,最后回到起点,遍历这棵树时每条边当且仅当走2次(来回) 给出两串序列,判断是否是同一棵树的不同遍历方式 题解:我们把每一个节点下 ...

  8. POJ1635 树的最小表示法(判断同构)

    Some major cities have subway systems in the form of a tree, i.e. between any pair of stations, ther ...

  9. luogu P5043 【模板】树同构 hash 最小表示法

    LINK:模板 树同构 题目说的很迷 给了一棵有根树 但是重新标号 言外之意还是一棵无根树 然后要求判断是否重构. 由于时无根的 所以一个比较显然的想法暴力枚举根. 然后做树hash或者树的最小表示法 ...

随机推荐

  1. js事件监听器用法实例详解

    这篇文章主要介绍了js事件监听器用法,以实例形式较为详细的分析了javascript事件监听器使用注意事项与相关技巧,需要的朋友可以参考下本文实例讲述了js事件监听器用法.分享给大家供大家参考.具体分 ...

  2. [Android进阶]学习AccessibilityService实现微信抢红包插件

    在你的手机更多设置或者高级设置中,我们会发现有个无障碍的功能,很多人不知道这个功能具体是干嘛的,其实这个功能是为了增强用户界面以帮助残障人士,或者可能暂时无法与设备充分交互的人们 它的具体实现是通过A ...

  3. ios tableview 适配横竖屏

    tableview.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;

  4. ios手势

    iOS 手势操作:拖动.捏合.旋转.点按.长按.轻扫.自定义 大 中 小   1.UIGestureRecognizer 介绍 手势识别在 iOS 中非常重要,他极大地提高了移动设备的使用便捷性. i ...

  5. MFC添加菜单事件

    双击draw.rc,就能看到.

  6. UbuntuLinux安装java

    jdk1.7,jdk1.8详情,参见:http://www.cnblogs.com/a2211009/p/4265225.html

  7. 使用getopt函数对windows命令行程序进行参数解析

    getopt()是libc的标准函数,很多语言中都能找到它的移植版本. // -b -p "c:\input" -o "e:\test\output" bool ...

  8. C# 遍历指定目录下的所有文件及文件夹

    // DirectoryInfo di = new DirectoryInfo(@"D:\Test"); // FindFile(di); static void FindFile ...

  9. Linux 下编译自己的 OpenJDK7 包括JVM和JDK API

    1.首先去 这里 http://download.java.net/openjdk/jdk7/ 下载OpenJDK7的源码zip包 2. 简要介绍下OpenJDK7中的目录 hotspot: 放有Op ...

  10. WCF----Stream对象限制操作

    WCF支持Stream操作,尤其对于传递size过大的消息而言,如要考虑传递消息的效率,WCF推荐通过Stream进行操作.然而,WCF Stream操作规定了一些限制,在我们编写相关程序时,需要特别 ...