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

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

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

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

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

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

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

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

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

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

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

/**
* code generated by JHelper
* More info: https://github.com/AlexeyDmitriev/JHelper
* @author xyiyy @https://github.com/xyiyy
*/ #include <iostream>
#include <fstream> //#####################
//Author:fraud
//Blog: http://www.cnblogs.com/fraud/
//#####################
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <sstream>
#include <ios>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <vector>
#include <string>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <climits>
#include <cctype> using namespace std;
#define pb(X) push_back(X)
#define rep(X, N) for(int X=0;X<N;X++)
#define ALL(X) (X).begin(),(X).end()
typedef unsigned long long ull; const int maxNode = ;
const int maxEdge = (maxNode << );
//
// Created by xyiyy on 2015/8/14.
// #ifndef ICPC_HASHTREE_HPP
#define ICPC_HASHTREE_HPP //树的同构,返回哈希值
//输入有根树的根,或者无根树的重心
typedef unsigned long long ull;
const ull MAGIC = ; //
// Created by xyfra_000 on 2015/8/14.
// #ifndef ICPC_ADJLIST_ARRAY_HPP
#define ICPC_ADJLIST_ARRAY_HPP #define Foredge(A, X) for(int A = From[X];A!=-1;A = Next[A]) int From[maxEdge], To[maxEdge];
int Next[maxEdge];
int Edgecnt; void init(int n) {
rep(i, n + )From[i] = -;
Edgecnt = ;
} void addedge(int u, int v) {
To[Edgecnt] = v;
Next[Edgecnt] = From[u];
From[u] = Edgecnt++;
} #endif //ICPC_ADJLIST_ARRAY_HPP ull powMod(ull a, int n) {
ull ret = 1ULL;
while (n) {
if (n & )ret *= a;
a *= a;
n >>= ;
}
return ret;
} struct Hash {
int length;
ull value; Hash() : length(), value() { } Hash(char c) : length(), value(c) { } Hash(int l, int v) : length(l), value(v) { }
}; bool operator<(const Hash &a, const Hash &b) {
return a.value < b.value;
} Hash operator+(const Hash &a, const Hash &b) {
return Hash(a.length + b.length, a.value * powMod(MAGIC, b.length) + b.value);
} void operator+=(Hash &a, Hash &b) {
a = a + b;
} vector<Hash> childs[maxNode]; Hash dfs(int pre, int cur) {
Hash ret;
childs[cur].clear();
for (int iter = From[cur]; iter != -; iter = Next[iter]) {
if (To[iter] != pre) {
childs[cur].pb(dfs(cur, To[iter]));
}
}
sort(ALL(childs[cur]));
for (vector<Hash>::iterator iter = childs[cur].begin(); iter != childs[cur].end(); iter++) {
ret += *iter;
}
Hash retL = Hash('(');
ret = '(' + ret + ')';
return ret;
} ull getHash(int root) {
return dfs(-, root).value;
} #endif //ICPC_HASHTREE_HPP //
// Created by xyfra_000 on 2015/8/14.
// #ifndef ICPC_TREEDIAMETER_HPP
#define ICPC_TREEDIAMETER_HPP //求树的直径
//可以通过修改dfs部分变成求带权的树的直径 vector<int> dist; void dfs(int p, int u, int d) {
dist[u] = d;
Foredge(i, u) {
if (To[i] != p) {
dfs(u, To[i], d + );
}
}
} int getDiameter(int n) {
dist.resize(n);
dfs(-, , );
int u = max_element(ALL(dist)) - dist.begin();
dfs(-, u, );
return *max_element(ALL(dist));
} #endif //ICPC_TREEDIAMETER_HPP int deg[maxNode];
int vis[maxNode]; class TaskH {
public:
void solve(std::istream &in, std::ostream &out) {
int n;
while (in >> n) {
vector<ull> ans[];
rep(times, ) {
int u, v;
init(n);
rep(i, n + )deg[i] = ;
rep(i, n + )vis[i] = ;
queue<int> q;
rep(i, n - ) {
in >> u >> v;
u--, v--;
deg[u]++;
deg[v]++;
addedge(u, v);
addedge(v, u);
}
int dia = getDiameter(n);
int num = n;
rep(i, n) {
if (deg[i] == ) {
q.push(i);
}
}
int gao = ;
if (dia & )gao++;
while (num > gao && !q.empty()) {
u = q.front();
q.pop();
vis[u] = ;
num--;
deg[u]--;
for (int i = From[u]; i != -; i = Next[i]) {
int v = To[i];
if (!vis[v]) {
deg[v]--;
if (deg[v] == ) {
q.push(v);
}
}
}
}
rep(i, n) {
if (!vis[i]) {
ans[times].pb(getHash(i));
}
}
}
bool ok = ;
rep(i, ans[].size()) {
rep(j, ans[].size()) {
if (ans[][i] == ans[][j])ok = ;
}
}
if (ok)out << "S" << endl;
else out << "N" << endl;
}
}
}; int main() {
std::ios::sync_with_stdio(false);
std::cin.tie();
TaskH solver;
std::istream &in(std::cin);
std::ostream &out(std::cout);
solver.solve(in, out);
return ;
}

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. HTTP_X_FORWARDED_FOR 和 REMOTE_ADDR的使用 php

    参考来源:http://qq398705749.iteye.com/blog/963818 php中HTTP_X_FORWARDED_FOR 和 REMOTE_ADDR的使用 1.REMOTE_ADD ...

  2. Solr Update备注

    参考资料: http://wiki.apache.org/solr/ExtractingRequestHandler#Sending_documents_to_Solr /update 标准的upda ...

  3. 转:Red Hat JBoss团队发布WildFly 8,全面支持Java EE 7并包含全新的嵌入式Web服务器

    原文来自于:http://www.infoq.com/cn/news/2014/02/wildfly8-launch Red Hat的JBoss部门今天宣布WildFly 8正式发布.其前身是JBos ...

  4. NGUI类之间的关系和架构

    NGUI Drawcall 1.使用同一个altals的元素尽量放在同一个UIPanel下面,在NGUI中,它消耗的drawcall是以每个Panel为独立计算单位进行计算的. 2.如果一个UIPan ...

  5. Windows服务器Pyton辅助运维--03.安装Visual Studio 的 Python 开发插件 PTVS

    PTVS (Python Tools for Visual Studio) http://pytools.codeplex.com/ 当前版本:2.1 RC PTVS (Python Tools fo ...

  6. RequireJS进阶(二)

    这一篇来认识下打包工具的paths参数,在入门一中就介绍了require.config方法的paths参数.用来配置jquery模块的文件名(jQuery作为AMD模块时id为“jquery”,但文件 ...

  7. 今天在写powershell脚本中犯的两个错误

    可能是因为牙痛没睡好,今天老是犯错,还是脚本写错,特别难调. 第一个错误: powershell脚本里面,函数与函数互相调用的传参.其实就像调用普通的cmdlet一样的写法,应该这么写: Add-Sc ...

  8. SQL Server 各任务所维护

    SQL Server 正在运行的代码查看 SELECT [Spid] = session_id , ecid , [Database] = DB_NAME(sp.dbid) , [User] = nt ...

  9. HTML, CSS学习笔记(完整版)

    第一章 div布局 前几课内容 .htm是早期的后缀.由于那时仅仅能支持长度为3的后缀.因此html与htm是一样的. shtml是server先处理然后再交给浏览器处理 #HTML小知识#之#XHT ...

  10. linux安装mysql5.1.56

    1.编译安装 > groupadd mysql #创建mysql组 > useradd -g mysql mysql #创建用户mysql并添加到mysql组中,这个用户主要是作为mysq ...