转载请注明出处: 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. Install FFmpeg, Mplayer, Mencoder, MP4Box, Flvtool2

    You can use the following tutorial to install ffmpeg and other video modules in your centos server.F ...

  2. oldboy第三天学习

    一.上课体验及感受 额第三天了.身心疲惫.上课一脸懵逼,是最标准的诠释.三个星期的疲惫感,更深了.很难,但是还要继续 写好作业.吸收知识. 二.三级列表 menu = { '北京':{ '海淀':{ ...

  3. java入门时的一些基本概念的理解(j2ee,j2se,j2me,jdk,sdk,jre,jvm,跨平台)

    首先声明,这篇文章是从网上粘贴过来的.原文地址是:http://www.cnblogs.com/wangaohui/archive/2012/11/28/2791999.html.感觉写的很好,所以粘 ...

  4. uva 10034 Problem A: Freckles

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  5. Android项目的图标

    项目的图标就是在AndroidManifest.xml中通过android:icon="@drawable/ic_launcher"来指定的,ic_launcher这张图片可以放在 ...

  6. fiddler Composer 构建请求

    Fiddler的作者把HTTP Request发射器取名叫Composer(中文意思是:乐曲的创造者),以前叫做Request Builder Fiddler Composer的功能就是用来创建HTT ...

  7. curl http认证

    有些站点需要http认证.(apache认证:http://blog.csdn.net/zf213/article/details/4252592) 如果访问http://test:123789@xx ...

  8. 简述WebService与.NET Remoting的区别及适应场合 WCF

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://zhoufoxcn.blog.51cto.com/792419/166990 为了 ...

  9. 使用Horner法则计算多项式的值

    计算Pn(x) = an * x^n + an-1 * x^(n-1) + ... + a1 * x + a0 直接计算,需要做的乘法次数 1+2+3+……+n = n(1+n)/2 = O(n2) ...

  10. tungsten开机启动及进程开启停止