首先找到树的中心或者中心,我这里是找中心,因为我们需要找一个相同的起点,然后最多2个中心就是树的宽度为偶数时,奇数时为1个。

找到之后需要对树进行hash,使得每个点都具备独特性,使之树的形态能够保证唯一,然后利用hash值,对树的每个节点下的节点进行排序,之后如果判定这两个树是一样的话,我只需要对树进行一次深搜并把遍历的顺序存进数组。然后直接按照数组中的值输出原来映射的字符串就好了。

#include<bits/stdc++.h>
#define LL long long
using namespace std; const int mod = 1e9 + ;
const int maxn = 1e5 + ;
const int seed = ;
char inp[], onp[]; struct Tree{
map<string, int>id;
vector<int>edge[maxn];
string anw[maxn], rip[maxn];
int _cnt, ctr[], siz[maxn], dep[maxn], fa[maxn];
LL Har[maxn]; ///将遍历顺序存进去
void done(int st, int fa){
if(fa == ) _cnt = ;
anw[_cnt ++] = rip[st];
for(auto x : edge[st]){
if(x == fa) continue;
done(x, st);
}
} ///hash技术
LL dfsh(int st, int fa){
Har[st] = seed;siz[st] = ;
for(auto x : edge[st]){
if(x == fa) continue;
dfsh(x, st);
siz[st] += siz[x];
}
sort(edge[st].begin(), edge[st].end(),
[&](int x, int y){return Har[x] < Har[y];});
for(auto x : edge[st]){
if(x == fa) continue;
Har[st] = (((Har[st] * Har[x]) % mod) ^ Har[x])% mod;
}
Har[st] = (Har[st] + siz[st]) % mod;
Har[st] = (Har[st] * Har[st]) % mod;
return Har[st];
} ///得到深度值
void getdep(int st, int Fa, int Dep){
dep[st] = Dep;fa[st] = Fa;
for(auto x : edge[st]){
if(x == fa[st]) continue;
getdep(x,st,Dep + );
}
} ///获取中点
void getCtr(int n){
getdep(, , );
ctr[] = max_element(dep + , dep + + n) - dep;
getdep(ctr[], , );
ctr[] = max_element(dep + , dep + + n) - dep;
int fdep = dep[ctr[]];
for(int i = ; i < fdep/; i ++)
ctr[] = fa[ctr[]];
ctr[] = ctr[];
if(fdep & ) ctr[] = fa[ctr[]];
} ///重置数据
void init(int n){
for(int i = ; i <= n; i ++)
edge[i].clear();
id.clear();_cnt = ;
} ///映射连接的符号,并存进对应的map值为下标的地方
int toid(string v){
if(id.find(v) != id.end()) return id[v];
rip[_cnt] = v;
return id[v] = _cnt ++;
} ///建图,映射值
void input(int n){
init(n);int l,r;
for(int i = ; i < n; i ++){
scanf("%s %s", inp, onp);
l = toid(inp); r = toid(onp);
edge[l].push_back(r);
edge[r].push_back(l);
}
}
}X, Y; void solve(){
for(int i = ; i < ; i ++)
for(int j = ; j < ; j ++)
if(X.dfsh(X.ctr[i], ) == Y.dfsh(Y.ctr[j], )){
X.done(X.ctr[i], );
Y.done(Y.ctr[j], );
return;
}
} int main(){
int n;while(~scanf("%d", &n)){
X.input(n);
Y.input(n);
X.getCtr(n);
Y.getCtr(n);
solve();
for(int i = ; i < n; i ++)
printf("%s %s\n",X.anw[i].c_str(), Y.anw[i].c_str());
}return ;
}

这次的代码可以说是照搬过来的,菜鸡的自己。

Subway (树中心 + 树hash)的更多相关文章

  1. bzoj 1669: [Usaco2006 Oct]Hungry Cows饥饿的奶牛【dp+树状数组+hash】

    最长上升子序列.虽然数据可以直接n方但是另写了个nlogn的 转移:f[i]=max(f[j]+1)(a[j]<a[i]) O(n^2) #include<iostream> #in ...

  2. MySQL的B+树索引和hash索引的区别

    简述一下索引: 索引是数据库表中一列或多列的值进行排序的一种数据结构:索引分为聚集索引和非聚集索引,聚集索引查询类似书的目录,快速定位查找的数据,非聚集索引查询一般需要再次回表查询一次,如果不使用索引 ...

  3. 字符串 --- KMP Eentend-Kmp 自动机 trie图 trie树 后缀树 后缀数组

    涉及到字符串的问题,无外乎这样一些算法和数据结构:自动机 KMP算法 Extend-KMP 后缀树 后缀数组 trie树 trie图及其应用.当然这些都是比较高级的数据结构和算法,而这里面最常用和最熟 ...

  4. 学习笔记--函数式线段树(主席树)(动态维护第K极值(树状数组套主席树))

    函数式线段树..资瓷 区间第K极值查询 似乎不过似乎划分树的效率更优于它,但是如果主席树套树状数组后,可以处理动态的第K极值.即资瓷插入删除,划分树则不同- 那么原理也比较易懂: 建造一棵线段树(权值 ...

  5. 【Todo】字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树

    另开一文分析字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树. 先来一个汇总, 算法: 本文中提到的字符串匹配算法有:KMP, BM, Horspool, Sunday, BF, ...

  6. 剑指Offer——Trie树(字典树)

    剑指Offer--Trie树(字典树) Trie树 Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种的单词.对于每一个单词,我们要判断他出没出现过,如果出现了,求第一次出现在第几个位 ...

  7. 主席树套树状数组——带修区间第k大zoj2112

    主席树带修第k大 https://www.cnblogs.com/Empress/p/4659824.html 讲的非常好的博客 首先按静态第k大建立起一组权值线段树(主席树) 然后现在要将第i个值从 ...

  8. HDU4819 Mosaic【树套树】

    LINK 题目大意 给你一个\(n*n\)矩阵,每个点有初始权值 q次询问每次把一个矩形的中心节点变成这个矩形中最大值和最小值的平均数 思路 很显然的树套树啊 就是一开始傻逼了没想到怎么去维护这个东西 ...

  9. HDU 4605 Magic Ball Game(可持续化线段树,树状数组,离散化)

    Magic Ball Game Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

随机推荐

  1. VS2017上在线和离线安装Qt插件(在线安装)

    版权声明:如需转载,请告知博主并声明出处 https://blog.csdn.net/CLinuxF/article/details/88816436文章目录前言在线安装离线安装(推荐)前言很多朋友喜 ...

  2. mysql分库 分表

    原文链接:http://www.jianshu.com/p/89311703b320 传统的分库分表传统的分库分表都是通过应用层逻辑实现的,对于数据库层面来说,都是普通的表和库.分库分库的原因 首先, ...

  3. 20165336 2017-2018-2 《Java程序设计》第4周学习总结

    20165336 2017-2018-2 <Java程序设计>第4周学习总结 教材学习内容总结 第五章 使用extends来定义一个子类. Object类是所有类的祖先类. 当子类和父类不 ...

  4. mysql大表更新sql的优化策略(转)

    看了该文章之后,很受启发,mysql在update时,一般也是先select.但注意,在Read Committed隔离级别下,如果没有使用索引,并不会锁住整个表, 还是只锁住满足查询条件的记录而已. ...

  5. (1.13)mysql优化数据库对象

    (1.13)mysql优化数据库对象 1.mysql优化数据库对象 [1.1]数据库对象类型优化 select * from test1 procedure analyse(); ,); --不要为那 ...

  6. 运行python文件时出错SyntaxError: Non-UTF-8 code starting with '\xb5' in file, but no encoding declared;

    今天ytkah在运行python文件时出现错误,提示如下,很明显这是没有定义python文件编码引起的问题,那么要怎么解决呢?很简单,在文件头部定义一下就可以了. File "hello.p ...

  7. TCP路由网络通信

    路由器 实现跨网段通信   路由器的工作原理是基于路由器中的路由表来实现数据包的路径选择 当路由器收到一个数据包的时候,会读取数据包的目标IP地址,根据目标IP地址来匹配路由表中的规则 单个路由器不会 ...

  8. 手把手教你用 Git(转)

    转自:http://blog.jobbole.com/78960/ 一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 二:SVN与Git的最主要的区别? SVN是集中式版本控制系统, ...

  9. 堆(heap)、栈(stack)、方法区(method)

    JVM内存分为3个区:堆(heap).栈(stack).方法区(method) 1.堆(heap):存储的全部对象,每个对象有个与之对应的class信息.即通过new关键字和构造器创建的对象.JVM只 ...

  10. [django]Django外键(ForeignKey)操作以及related_name的作用

    https://blog.csdn.net/hpu_yly_bj/article/details/78939748 related_name表面作用 加上 核心related_name作用 https ...