转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3933

给你两棵无根树,让你判断这两棵树是否同构

不会判断树同构,果断抄了个模板,乱搞给过掉了。

首先由于给的是无根树,而要判断无根树是否同构得以重心为根,然后做一个括号序列的哈希。

于是我们需要先找出重心,要找树的重心得先知道直径。

找出直径,直径上的点的个数是偶数,那么重心是中间的两个点,如果是奇数个,那么重心是中间那个。

或者说是根据拓排,每次度数为1的点入队,留下的最后一批就是。

然而我当时脑抽了一下,求好直径,后用第二种再去搞。。。其实求直径的时候保存一下路径就好了。

最后,如果有两个重心就做两次哈希,得到两个哈希值,一个就一次。

最后把两棵树的哈希值比一下是否有相同的。

  1. /**
  2. * code generated by JHelper
  3. * More info: https://github.com/AlexeyDmitriev/JHelper
  4. * @author xyiyy @https://github.com/xyiyy
  5. */
  6.  
  7. #include <iostream>
  8. #include <fstream>
  9.  
  10. //#####################
  11. //Author:fraud
  12. //Blog: http://www.cnblogs.com/fraud/
  13. //#####################
  14. //#pragma comment(linker, "/STACK:102400000,102400000")
  15. #include <iostream>
  16. #include <sstream>
  17. #include <ios>
  18. #include <iomanip>
  19. #include <functional>
  20. #include <algorithm>
  21. #include <vector>
  22. #include <string>
  23. #include <list>
  24. #include <queue>
  25. #include <deque>
  26. #include <stack>
  27. #include <set>
  28. #include <map>
  29. #include <cstdio>
  30. #include <cstdlib>
  31. #include <cmath>
  32. #include <cstring>
  33. #include <climits>
  34. #include <cctype>
  35.  
  36. using namespace std;
  37. #define pb(X) push_back(X)
  38. #define rep(X, N) for(int X=0;X<N;X++)
  39. #define ALL(X) (X).begin(),(X).end()
  40. typedef unsigned long long ull;
  41.  
  42. const int maxNode = ;
  43. const int maxEdge = (maxNode << );
  44. //
  45. // Created by xyiyy on 2015/8/14.
  46. //
  47.  
  48. #ifndef ICPC_HASHTREE_HPP
  49. #define ICPC_HASHTREE_HPP
  50.  
  51. //树的同构,返回哈希值
  52. //输入有根树的根,或者无根树的重心
  53. typedef unsigned long long ull;
  54. const ull MAGIC = ;
  55.  
  56. //
  57. // Created by xyfra_000 on 2015/8/14.
  58. //
  59.  
  60. #ifndef ICPC_ADJLIST_ARRAY_HPP
  61. #define ICPC_ADJLIST_ARRAY_HPP
  62.  
  63. #define Foredge(A, X) for(int A = From[X];A!=-1;A = Next[A])
  64.  
  65. int From[maxEdge], To[maxEdge];
  66. int Next[maxEdge];
  67. int Edgecnt;
  68.  
  69. void init(int n) {
  70. rep(i, n + )From[i] = -;
  71. Edgecnt = ;
  72. }
  73.  
  74. void addedge(int u, int v) {
  75. To[Edgecnt] = v;
  76. Next[Edgecnt] = From[u];
  77. From[u] = Edgecnt++;
  78. }
  79.  
  80. #endif //ICPC_ADJLIST_ARRAY_HPP
  81.  
  82. ull powMod(ull a, int n) {
  83. ull ret = 1ULL;
  84. while (n) {
  85. if (n & )ret *= a;
  86. a *= a;
  87. n >>= ;
  88. }
  89. return ret;
  90. }
  91.  
  92. struct Hash {
  93. int length;
  94. ull value;
  95.  
  96. Hash() : length(), value() { }
  97.  
  98. Hash(char c) : length(), value(c) { }
  99.  
  100. Hash(int l, int v) : length(l), value(v) { }
  101. };
  102.  
  103. bool operator<(const Hash &a, const Hash &b) {
  104. return a.value < b.value;
  105. }
  106.  
  107. Hash operator+(const Hash &a, const Hash &b) {
  108. return Hash(a.length + b.length, a.value * powMod(MAGIC, b.length) + b.value);
  109. }
  110.  
  111. void operator+=(Hash &a, Hash &b) {
  112. a = a + b;
  113. }
  114.  
  115. vector<Hash> childs[maxNode];
  116.  
  117. Hash dfs(int pre, int cur) {
  118. Hash ret;
  119. childs[cur].clear();
  120. for (int iter = From[cur]; iter != -; iter = Next[iter]) {
  121. if (To[iter] != pre) {
  122. childs[cur].pb(dfs(cur, To[iter]));
  123. }
  124. }
  125. sort(ALL(childs[cur]));
  126. for (vector<Hash>::iterator iter = childs[cur].begin(); iter != childs[cur].end(); iter++) {
  127. ret += *iter;
  128. }
  129. Hash retL = Hash('(');
  130. ret = '(' + ret + ')';
  131. return ret;
  132. }
  133.  
  134. ull getHash(int root) {
  135. return dfs(-, root).value;
  136. }
  137.  
  138. #endif //ICPC_HASHTREE_HPP
  139.  
  140. //
  141. // Created by xyfra_000 on 2015/8/14.
  142. //
  143.  
  144. #ifndef ICPC_TREEDIAMETER_HPP
  145. #define ICPC_TREEDIAMETER_HPP
  146.  
  147. //求树的直径
  148. //可以通过修改dfs部分变成求带权的树的直径
  149.  
  150. vector<int> dist;
  151.  
  152. void dfs(int p, int u, int d) {
  153. dist[u] = d;
  154. Foredge(i, u) {
  155. if (To[i] != p) {
  156. dfs(u, To[i], d + );
  157. }
  158. }
  159. }
  160.  
  161. int getDiameter(int n) {
  162. dist.resize(n);
  163. dfs(-, , );
  164. int u = max_element(ALL(dist)) - dist.begin();
  165. dfs(-, u, );
  166. return *max_element(ALL(dist));
  167. }
  168.  
  169. #endif //ICPC_TREEDIAMETER_HPP
  170.  
  171. int deg[maxNode];
  172. int vis[maxNode];
  173.  
  174. class TaskH {
  175. public:
  176. void solve(std::istream &in, std::ostream &out) {
  177. int n;
  178. while (in >> n) {
  179. vector<ull> ans[];
  180. rep(times, ) {
  181. int u, v;
  182. init(n);
  183. rep(i, n + )deg[i] = ;
  184. rep(i, n + )vis[i] = ;
  185. queue<int> q;
  186. rep(i, n - ) {
  187. in >> u >> v;
  188. u--, v--;
  189. deg[u]++;
  190. deg[v]++;
  191. addedge(u, v);
  192. addedge(v, u);
  193. }
  194. int dia = getDiameter(n);
  195. int num = n;
  196. rep(i, n) {
  197. if (deg[i] == ) {
  198. q.push(i);
  199. }
  200. }
  201. int gao = ;
  202. if (dia & )gao++;
  203. while (num > gao && !q.empty()) {
  204. u = q.front();
  205. q.pop();
  206. vis[u] = ;
  207. num--;
  208. deg[u]--;
  209. for (int i = From[u]; i != -; i = Next[i]) {
  210. int v = To[i];
  211. if (!vis[v]) {
  212. deg[v]--;
  213. if (deg[v] == ) {
  214. q.push(v);
  215. }
  216. }
  217. }
  218. }
  219. rep(i, n) {
  220. if (!vis[i]) {
  221. ans[times].pb(getHash(i));
  222. }
  223. }
  224. }
  225. bool ok = ;
  226. rep(i, ans[].size()) {
  227. rep(j, ans[].size()) {
  228. if (ans[][i] == ans[][j])ok = ;
  229. }
  230. }
  231. if (ok)out << "S" << endl;
  232. else out << "N" << endl;
  233. }
  234. }
  235. };
  236.  
  237. int main() {
  238. std::ios::sync_with_stdio(false);
  239. std::cin.tie();
  240. TaskH solver;
  241. std::istream &in(std::cin);
  242. std::ostream &out(std::cout);
  243. solver.solve(in, out);
  244. return ;
  245. }

uva12489 Combating cancer(树同构)的更多相关文章

  1. BZOJ4337: BJOI2015 树的同构(hash 树同构)

    题意 题目链接 Sol 树的同构问题,直接拿hash判一下,具体流程大概是这样的: 首先转化为有根树,预处理出第\(i\)棵树以\(j\)为根时的hash值. 那么两个树同构当且仅当把两棵树的hash ...

  2. Luogu 5043 【模板】树同构([BJOI2015]树的同构)

    BZOJ 4337 简单记录一种树哈希的方法:以$x$为根的子树的哈希值为$\sum_{y \in son(x)}f_y*base_i$,$f_y$表示以$y$为根的树的哈希值,其中$i$表示$f_y ...

  3. 『Andrew and Chemistry 树同构』

    Andrew and Chemistry Description During the chemistry lesson Andrew learned that the saturated hydro ...

  4. 【CF1252F】Regular Forestation(重心,树同构)

    题意:给定一棵n个点的树,问删去某个点之后所有的树同构,这样分割出来的树最多能有几棵 n<=4000 思路:分割成至少两个size相等的联通块之后size必定小于n/2,与树的重心的定义相同 预 ...

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

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

  6. 【BZOJ3197】[Sdoi2013]assassin 树同构+动态规划+KM

    [BZOJ3197][Sdoi2013]assassin Description Input Output Sample Input 4 1 2 2 3 3 4 0 0 1 1 1 0 0 0 Sam ...

  7. 【BZOJ3162】独钓寒江雪 树同构+DP

    [BZOJ3162]独钓寒江雪 题解:先进行树hash,方法是找重心,如果重心有两个,则新建一个虚点将两个重心连起来,新点即为新树的重心.将重心当做根进行hash,hash函数不能太简单,我的方法是: ...

  8. Regular Forestation CodeForces - 1252F(树同构)

    Regular Forestation \[ Time Limit: 1000 ms\quad Memory Limit: 262144 kB \] 题意 给出一个节点为 \(n\) 的树,问删掉树上 ...

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

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

随机推荐

  1. iOS UITableView的使用大全-备用

    首先.对UITableView进行讲解,下面有对它进行实际的应用 UITableView 显示大型内容的列表 单行,多列 垂直滚动,没有水平滚动 大量的数据集 性能强大,而且普遍存在于iPhone的应 ...

  2. (转)關於flashback query的ORA-01466錯誤

    摘自:http://blog.sina.com.cn/s/blog_70a2bdb80100pqid.html 使用Oracle 10g 新特性flashback query來查詢過去修改並已提交的記 ...

  3. 功能:使用QQ号登陆,并加上微信和短信提醒,是否增量备份可选,阿里大鱼短信发送开发与测试,聚合数据(用JSON发短信,比较清楚)

    微博就可以,所以其它软件也可以http://desktop.weibo.com/ http://blog.csdn.net/jueblog/article/details/14497181http:/ ...

  4. UML建模之状态图(Statechart Diagram)

     状态图目录: 一.状态图简介(Brief introduction) 二.状态图元素(State Diagram Elements) 1.状态(States) 2.转移(Transitions) 3 ...

  5. 兼容ie6/ff/ch/op的div+css实现的圆角框

    <!DOCTYPE html> <html> <head> <title>青春不迷茫:寻梦时代的“蚁族”逆袭之旅- 职场管理专题-中国人力资源开发网-中 ...

  6. nginx 配置自签名的ssl证书

    最近要搭一个https的测试环境,使用nginx做反向代理. 网上找过不少资料,但过程不是很完整,吃了不少亏,故把自己的操作过程总结下来.如果你刚好遇到这个问题,希望对你有帮助! ********** ...

  7. android后台截屏实现(3)--编译screencap

    修改好之后就要编译了,screencap的编译是要在源码环境中进行的. 将修改后的screencap.cpp文件替换源码中的原始文件,然后修改screencap的Android.mk文件,修改后的文件 ...

  8. javadoc简介

    Javadoc是Sun公司提供的一个技术,它从程序源代码中抽取类.方法.成员等注释形成一个和源代码配套的API帮助文档.也就是说,只要在编写程序时以一套特定的标签作注释,在程序编写完成后,通过Java ...

  9. [转]Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果

    转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17539199),请尊重他人的辛勤劳动成果,谢谢! 我在上一 ...

  10. openwrt上网配置的一些理解(四)

    这次要解决的问题是3g上网和wan口上往可以随意切换,当然能够叠加也是好事,不过这不是我关心的.下面还是修改3个文件network,firewall,multiwan.首先在network中加入界面配 ...