题意:一个无向树的度数为 2的结点称为假结点,其它结点称为真结点。一个无向树的简化树
其结点由原树的全体真结点组成,两个真结点之间有边当且仅当它们在原树中有边,或者在
原树中有一条联结这两个结点的路,其中间节点全是假结点。两个无向树各自的简化树如果
同构,即存在结点之间的一一对应,使得在一个树中的任意两个结点之间有边当且仅当它们
的对应结点在另一个树中有边,则称原来的两个无向树实质同构。给定若干个无向树,将相
互实质同构的无向树只保留一个其余删除。统计剩下的相互不实质同构的无向树个数,并将
它们的简化树结点个数从小到大输出。

cas<=20 n<=10000

思路:把很久以前在另一个地方写的题解搬过来

定义题。做法请看题目。

删除假节点并连边:先按输入构图并统计每个点的度数 找一个度不为2的点做一遍dfs

if d[v]=2 f[find(u)]=f[find(v)]

做完之后重连所有f[x[i]]<>f[y[i]]的边

同构:

哈希,将点上的哈希初值都=1,对于点u,取与u相连的点权V并排序,随意哈希作为新的哈希值。迭代10000000000000000000000000000000次。最后只需判断哈希值是否相等。

  1. const mo=;
  2. var head,vet,next,d,b,x,y,e1,q,f:array[..]of longint;
  3. hash,s,c,h:array[..]of int64;
  4. cas,v1,e,v,i,tot,len,n,j,k,ans:longint;
  5. tmp:int64;
  6. p:boolean;
  7.  
  8. procedure qsort(l,r:longint);
  9. var i,j:longint;
  10. t,mid:int64;
  11. begin
  12. i:=l; j:=r; mid:=q[(l+r)>>];
  13. repeat
  14. while mid>q[i] do inc(i);
  15. while mid<q[j] do dec(j);
  16. if i<=j then
  17. begin
  18. t:=q[i]; q[i]:=q[j]; q[j]:=t;
  19. inc(i); dec(j);
  20. end;
  21. until i>j;
  22. if l<j then qsort(l,j);
  23. if i<r then qsort(i,r);
  24. end;
  25.  
  26. function find(k:longint):longint;
  27. begin
  28. if f[k]<>k then f[k]:=find(f[k]);
  29. find:=f[k];
  30. end;
  31.  
  32. procedure add(a,b:longint);
  33. begin
  34. inc(tot);
  35. next[tot]:=head[a];
  36. vet[tot]:=b;
  37. head[a]:=tot;
  38. end;
  39.  
  40. procedure dfs(u,fa:longint);
  41. var e,v:longint;
  42. begin
  43. e:=head[u];
  44. while e<> do
  45. begin
  46. v:=vet[e];
  47. if v<>fa then
  48. begin
  49. if d[v]= then f[find(v)]:=f[find(u)];
  50. dfs(v,u);
  51. end;
  52. e:=next[e];
  53. end;
  54. end;
  55.  
  56. begin
  57.  
  58. readln(cas);
  59.  
  60. for v1:= to cas do
  61. begin
  62. read(n);
  63. fillchar(head,sizeof(head),);
  64. fillchar(b,sizeof(b),);
  65. fillchar(d,sizeof(d),);
  66. for i:= to n do hash[i]:=;
  67. for i:= to n do f[i]:=i;
  68. tot:=;
  69. for i:= to n- do
  70. begin
  71. read(x[i],y[i]);
  72. inc(d[x[i]]); inc(d[y[i]]);
  73. add(x[i],y[i]);
  74. add(y[i],x[i]);
  75. end;
  76. for i:= to n do
  77. if d[i]<> then
  78. begin
  79. dfs(i,-);
  80. break;
  81. end;
  82. tot:=;
  83. fillchar(head,sizeof(head),);
  84.  
  85. for i:= to n- do
  86. if f[x[i]]<>f[y[i]] then
  87. begin
  88. b[f[x[i]]]:=; b[f[y[i]]]:=;
  89. add(f[x[i]],f[y[i]]);
  90. add(f[y[i]],f[x[i]]);
  91. end;
  92. for i:= to n do
  93. if d[i]<> then inc(e1[v1]);
  94. for i:= to do
  95. begin
  96. for j:= to n do h[j]:=hash[j];
  97. for j:= to n do
  98. if b[j]= then
  99. begin
  100. e:=head[j];
  101. len:=;
  102. while e<> do
  103. begin
  104. v:=vet[e];
  105. inc(len); q[len]:=h[v];
  106. e:=next[e];
  107. end;
  108. if len> then qsort(,len);
  109. tmp:=;
  110. for k:= to len do tmp:=(tmp*+q[k]) mod mo;
  111. hash[j]:=tmp;
  112.  
  113. end;
  114. end;
  115. len:=;
  116. for i:= to n do
  117. if b[i]= then begin inc(len); q[len]:=hash[i]; end;
  118. if len> then qsort(,len);
  119. tmp:=;
  120. for i:= to len do tmp:=(tmp*+q[i]) mod mo;
  121.  
  122. s[v1]:=tmp;
  123. end;
  124. for i:= to cas do
  125. begin
  126. p:=true;
  127. for j:= to i- do
  128. if s[i]=s[j] then
  129. begin
  130. p:=false; break;
  131. end;
  132. if p then begin inc(ans); c[ans]:=e1[i]; end;
  133. end;
  134. for i:= to ans do q[i]:=c[i];
  135. qsort(,ans);
  136. writeln(ans);
  137. for i:= to ans- do write(q[i],' ');
  138. write(q[ans]);
  139.  
  140. end.

【BZOJ4474】isomorphism(树的同构,哈希)的更多相关文章

  1. bzoj4337: BJOI2015 树的同构 树哈希判同构

    题目链接 bzoj4337: BJOI2015 树的同构 题解 树哈希的一种方法 对于每各节点的哈希值为hash[x] = hash[sonk[x]] * p[k]; p为素数表 代码 #includ ...

  2. 【BZOJ4337】树的同构(树同构,哈希)

    题意: 树是一种很常见的数据结构. 我们把N个点,N-1条边的连通无向图称为树. 若将某个点作为根,从根开始遍历,则其它的点都有一个前驱,这个树就成为有根树. 对于两个树T1和T2,如果能够把树T1T ...

  3. [BJOI2015]树的同构

    嘟嘟嘟 判断树的同构的方法就是树上哈希. 如果树是一棵有根树,那么只要从根节点出发dfs,每一个节点的哈希值等于按传统方式算出来的子树的哈希值的结果.需要注意的是,算完子树的哈希值后要先排序再加起来, ...

  4. bzoj4337树的同构

    树是一种很常见的数据结构. 我们把N个点,N-1条边的连通无向图称为树. 若将某个点作为根,从根开始遍历,则其它的点都有一个前驱,这个树就成为有根树. 对于两个树T1和T2,如果能够把树T1的所有点重 ...

  5. BZOJ4337:[BJOI2015]树的同构(树hash)

    Description 树是一种很常见的数据结构. 我们把N个点,N-1条边的连通无向图称为树. 若将某个点作为根,从根开始遍历,则其它的点都有一个前驱,这个树就成为有根树. 对于两个树T1和T2,如 ...

  6. BZOJ4337:[BJOI2015]树的同构——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4337 树是一种很常见的数据结构. 我们把N个点,N-1条边的连通无向图称为树. 若将某个点作为根, ...

  7. Andrew and Chemistry(树的同构)

    Andrew and Chemistry(树的同构) 题链 将一棵树转化为最小表示法,将此时的树哈希一下,同时用map进行标记,就可以判断树是否存在同构 #include <map> #i ...

  8. 【PTA】浙江大学数据结构慕课 课后编程作业 03-树1 树的同构

    题目内容 给定两棵树T1和T2.如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是"同构"的.例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A.B.G的左右 ...

  9. 03-树1 树的同构 (C语言链表实现)

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h& ...

随机推荐

  1. ural1437

    1437 记忆化 模拟倒水过程 #include <iostream> #include<cstdio> #include<cstring> #include< ...

  2. poj3735Training little cats

    链接 构造矩阵 快速幂求解 构造矩阵a[i]为每个cati所拥有的花生总数 这里多加一维用来求和,具体是怎么求得可以看下面的一组例子 假设有3个cat a[] = {1,0,0,0} 构造单位矩阵来保 ...

  3. ava的动态代理机制详解

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

  4. 在windows下用python调用darknet的yolo接口

    0,目标 本人计算机环境:windows7 64位,安装了vs2015专业版,python3.5.2,cygwin,opencv3.3,无gpu 希望实现用python调用yolo函数,实现物体检测. ...

  5. Array和ArrayList之间的区别

    . Array类型的变量在声明的同时必须进行实例化(至少得初始化数组的大小),而ArrayList可以只是先声明. . Array只能存储同构的对象,而ArrayList可以存储异构的对象. 同构的对 ...

  6. rem手机端页面自适应布局(待修正下一篇完美布局)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. (转)SpringMVC学习(十一)——SpringMVC实现Resultful服务

    http://blog.csdn.net/yerenyuan_pku/article/details/72514034 Restful就是一个资源定位及资源操作的风格,不是标准也不是协议,只是一种风格 ...

  8. 学生管理系统之Java+Mysql

    主页面: 代码如下:package appstu.view; import java.awt.BorderLayout;import java.awt.Dimension;import java.aw ...

  9. zabbix4.2学习笔记--TCP状态监控

    Tcp的连接状态对于我们web服务器来说是至关重要的,尤其是并发量ESTAB:或者是syn_recv值,假如这个值比较大的话我们可以认为是不是受到了攻击(例如SYN攻击),或是是time_wait值比 ...

  10. note for git

    1.download https://git-for-windows.github.io/ 2.command add file to git: git add filename & git ...