uva12489 Combating cancer(树同构)
转载请注明出处: 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(树同构)的更多相关文章
- BZOJ4337: BJOI2015 树的同构(hash 树同构)
题意 题目链接 Sol 树的同构问题,直接拿hash判一下,具体流程大概是这样的: 首先转化为有根树,预处理出第\(i\)棵树以\(j\)为根时的hash值. 那么两个树同构当且仅当把两棵树的hash ...
- Luogu 5043 【模板】树同构([BJOI2015]树的同构)
BZOJ 4337 简单记录一种树哈希的方法:以$x$为根的子树的哈希值为$\sum_{y \in son(x)}f_y*base_i$,$f_y$表示以$y$为根的树的哈希值,其中$i$表示$f_y ...
- 『Andrew and Chemistry 树同构』
Andrew and Chemistry Description During the chemistry lesson Andrew learned that the saturated hydro ...
- 【CF1252F】Regular Forestation(重心,树同构)
题意:给定一棵n个点的树,问删去某个点之后所有的树同构,这样分割出来的树最多能有几棵 n<=4000 思路:分割成至少两个size相等的联通块之后size必定小于n/2,与树的重心的定义相同 预 ...
- luogu P5043 【模板】树同构 hash 最小表示法
LINK:模板 树同构 题目说的很迷 给了一棵有根树 但是重新标号 言外之意还是一棵无根树 然后要求判断是否重构. 由于时无根的 所以一个比较显然的想法暴力枚举根. 然后做树hash或者树的最小表示法 ...
- 【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 ...
- 【BZOJ3162】独钓寒江雪 树同构+DP
[BZOJ3162]独钓寒江雪 题解:先进行树hash,方法是找重心,如果重心有两个,则新建一个虚点将两个重心连起来,新点即为新树的重心.将重心当做根进行hash,hash函数不能太简单,我的方法是: ...
- Regular Forestation CodeForces - 1252F(树同构)
Regular Forestation \[ Time Limit: 1000 ms\quad Memory Limit: 262144 kB \] 题意 给出一个节点为 \(n\) 的树,问删掉树上 ...
- 【BZOJ4337】树的同构(树同构,哈希)
题意: 树是一种很常见的数据结构. 我们把N个点,N-1条边的连通无向图称为树. 若将某个点作为根,从根开始遍历,则其它的点都有一个前驱,这个树就成为有根树. 对于两个树T1和T2,如果能够把树T1T ...
随机推荐
- iOS UITableView的使用大全-备用
首先.对UITableView进行讲解,下面有对它进行实际的应用 UITableView 显示大型内容的列表 单行,多列 垂直滚动,没有水平滚动 大量的数据集 性能强大,而且普遍存在于iPhone的应 ...
- (转)關於flashback query的ORA-01466錯誤
摘自:http://blog.sina.com.cn/s/blog_70a2bdb80100pqid.html 使用Oracle 10g 新特性flashback query來查詢過去修改並已提交的記 ...
- 功能:使用QQ号登陆,并加上微信和短信提醒,是否增量备份可选,阿里大鱼短信发送开发与测试,聚合数据(用JSON发短信,比较清楚)
微博就可以,所以其它软件也可以http://desktop.weibo.com/ http://blog.csdn.net/jueblog/article/details/14497181http:/ ...
- UML建模之状态图(Statechart Diagram)
状态图目录: 一.状态图简介(Brief introduction) 二.状态图元素(State Diagram Elements) 1.状态(States) 2.转移(Transitions) 3 ...
- 兼容ie6/ff/ch/op的div+css实现的圆角框
<!DOCTYPE html> <html> <head> <title>青春不迷茫:寻梦时代的“蚁族”逆袭之旅- 职场管理专题-中国人力资源开发网-中 ...
- nginx 配置自签名的ssl证书
最近要搭一个https的测试环境,使用nginx做反向代理. 网上找过不少资料,但过程不是很完整,吃了不少亏,故把自己的操作过程总结下来.如果你刚好遇到这个问题,希望对你有帮助! ********** ...
- android后台截屏实现(3)--编译screencap
修改好之后就要编译了,screencap的编译是要在源码环境中进行的. 将修改后的screencap.cpp文件替换源码中的原始文件,然后修改screencap的Android.mk文件,修改后的文件 ...
- javadoc简介
Javadoc是Sun公司提供的一个技术,它从程序源代码中抽取类.方法.成员等注释形成一个和源代码配套的API帮助文档.也就是说,只要在编写程序时以一套特定的标签作注释,在程序编写完成后,通过Java ...
- [转]Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果
转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17539199),请尊重他人的辛勤劳动成果,谢谢! 我在上一 ...
- openwrt上网配置的一些理解(四)
这次要解决的问题是3g上网和wan口上往可以随意切换,当然能够叠加也是好事,不过这不是我关心的.下面还是修改3个文件network,firewall,multiwan.首先在network中加入界面配 ...