HDU5732 Subway

题意:

给出两棵大小为\(N\)的同构树,要求输出对应的节点

\(N\le 10^5\)

题解:

由于重心最多只有两个,找到重心之后以重心为根进行树哈希,找到相同哈希值的根之后递归输出即可

输出儿子的时候要先对哈希值排序,保证递归进去的儿子节点也是同构的

这里用的哈希方法是\(f[u] = 1 + \sum_{v\in son_u}f[v]\cdot prime[sz[v]]\)

view code
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
typedef uint64_t ull;
const int MAXN = 2e5+7;
vector<int> prime;
void sieve(){
vector<bool> pm(MAXN,true);
for(int i = 2; i < MAXN; i++){
if(pm[i]) prime.push_back(i);
for(int j = 0; j < (int)prime.size(); j++){
if(i*prime[j]>=MAXN) break;
pm[i*prime[j]] = false;
if(i%prime[j]==0) break;
}
}
}
int n;
struct Tree{
vector<int> G[MAXN];
map<string,int> msk;
string name[MAXN];
int sz[MAXN],maxsz[MAXN];
ull hashval[MAXN];
int tot,root;
void clear(){
for(int i = 1; i <= tot; i++) G[i].clear();
tot = 0;
msk.clear();
}
int getID(string &s){
if(!msk.count(s)){
msk[s] = ++tot;
name[tot] = s;
}
return msk[s];
}
void dfs(int u, int f){
sz[u] = 1; maxsz[u] = 0;
for(int v : G[u]){
if(v==f) continue;
dfs(v,u);
sz[u] += sz[v];
maxsz[u] = max(maxsz[u],sz[v]);
}
maxsz[u] = max(maxsz[u],tot-sz[u]);
}
void getHash(int u, int f){
sz[u] = 1;
hashval[u] = 1ull;
for(int v : G[u]){
if(v==f) continue;
getHash(v,u);
sz[u] += sz[v];
hashval[u] += hashval[v] * prime[sz[v]];
}
}
}tr[2];
void match(int u0, int u1, int f0, int f1){
cout << tr[0].name[u0] << ' ' << tr[1].name[u1] << endl;
tr[0].hashval[f0] = UINT64_MAX;
tr[1].hashval[f1] = UINT64_MAX;
sort(tr[0].G[u0].begin(),tr[0].G[u0].end(),[&](const int &x, const int &y){
return tr[0].hashval[x] < tr[0].hashval[y];
});
sort(tr[1].G[u1].begin(),tr[1].G[u1].end(),[&](const int &x, const int &y){
return tr[1].hashval[x] < tr[1].hashval[y];
});
int m = (int)tr[0].G[u0].size() - (f0==0?0:1);
for(int i = 0; i < m; i++)
match(tr[0].G[u0][i],tr[1].G[u1][i],u0,u1);
}
void solve(){
tr[0].clear(); tr[1].clear();
for(int t = 0; t < 2; t++){
for(int i = 1; i < n; i++){
string s1, s2;
cin >> s1 >> s2;
int u = tr[t].getID(s1);
int v = tr[t].getID(s2);
tr[t].G[u].push_back(v);
tr[t].G[v].push_back(u);
}
}
tr[0].dfs(1,0);
int hsz = *min_element(tr[0].maxsz+1,tr[0].maxsz+1+n);
for(int i = 1; i <= n; i++){
if(tr[0].maxsz[i]==hsz){
tr[0].root = i;
break;
}
}
tr[0].getHash(tr[0].root,0);
ull hax = tr[0].hashval[tr[0].root];
tr[1].dfs(1,0);
for(int i = 1; i <= n; i++){
if(tr[1].maxsz[i]==hsz){
tr[1].getHash(i,0);
if(hax==tr[1].hashval[i]){
tr[1].root = i;
break;
}
}
}
match(tr[0].root,tr[1].root,0,0);
} int main(){
____();
sieve();
while(cin >> n) solve();
return 0;
}

HDU5732 Subway【树重心 树哈希】的更多相关文章

  1. B+树索引和哈希索引的区别——我在想全文搜索引擎为啥不用hash索引而非得使用B+呢?

    哈希文件也称为散列文件,是利用哈希存储方式组织的文件,亦称为直接存取文件.它类似于哈希表,即根据文件中关键字的特点,设计一个哈希函数和处理冲突的方法,将记录哈希到存储设备上. 在哈希文件中,是使用一个 ...

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

      导读 在MySQL里常用的索引数据结构有B+树索引和哈希索引两种,我们来看下这两种索引数据结构的区别及其不同的应用建议. 二者区别 备注:先说下,在MySQL文档里,实际上是把B+树索引写成了BT ...

  3. B+树索引和哈希索引的区别[转]

    导读 在MySQL里常用的索引数据结构有B+树索引和哈希索引两种,我们来看下这两种索引数据结构的区别及其不同的应用建议. 二者区别 备注:先说下,在MySQL文档里,实际上是把B+树索引写成了BTRE ...

  4. MySQL B+树索引和哈希索引的区别(转 JD二面)

    导读 在MySQL里常用的索引数据结构有B+树索引和哈希索引两种,我们来看下这两种索引数据结构的区别及其不同的应用建议. 二者区别 备注:先说下,在MySQL文档里,实际上是把B+树索引写成了BTRE ...

  5. Atitit 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树 attilax理解与总结

    Atitit 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树 attilax理解与总结 1.1. 树形结构-- 一对多的关系1 1.2. 树的相关术语: 1 1.3. 常见的树形结构 ...

  6. 字典树(Trie树)的实现及应用

    >>字典树的概念 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树.与二叉查找树不同,Trie树的 ...

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

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

  8. 【bzoj1901】dynamic ranking(带修改主席树/树套树)

    题面地址(权限题) 不用权限题的地址 首先说说怎么搞带修改主席树? 回忆一般的kth问题,我们的主席树求的是前缀和,这样我们在目标区间的左右端点的主席树差分下就能求出kth. 那么我们如何支持修改操作 ...

  9. 字典树 trie树 学习

    一字典树 字典树,又称单词查找树,Trie树,是一种树形结构,哈希表的一个变种   二.性质 根节点不包含字符,除根节点以外的每一个节点都只包含一个字符: 从根节点到某一节点,路径上经过的字符串连接起 ...

随机推荐

  1. HP PROLIANT DL388 GEN10 (故障3019)SPP损坏

    HP PROLIANT DL388 GEN10 (故障3019)SPP损坏 1. 开机硬件自检,提示错误ERROR 3019: 2. 根据服务器版本GEN10下载最新固件SPP,可找服务商或者HP售后 ...

  2. AI智能皮肤测试仪助力美业数字化营销 实现门店与用户双赢局面

    当皮肤遇到AI智能,会有怎么样的火花呢?随着生活水平的提升,人们对肌肤保养护理的需求也越来越高,人要美,皮肤养护也要更精准,数字化必将成为美业发展的新契机.新机遇下肌肤管家SkinRun为美业客户提供 ...

  3. 🎉 Element UI for Vue 3.0 来了!

    第一个使用 TypeScript + Vue 3.0 Composition API 重构的组件库 Element Plus 发布了 ~ 2016 年 3 月 13 日 Element 悄然诞生,经历 ...

  4. CentOS 7 下安装 mysql ,以及用到的命令

    VMware虚拟机装好后,再装个CentOS7系统,以上环境自行百度... 一.Linux下查看mysql是否安装 1.指令ps -ef|grep mysql [root@localhost 桌面]# ...

  5. 5V充8.4V,5V升压8.4V给电池充电的芯片电路

    5V充8.4V的锂电池,需要把USB口的5V输入,升压转换成8.4V来给两串电池充电. 5V升压8.4V给锂电池充电的专门充电IC 集成了5V升压8.4V电路和充电管理电路的PL7501C 如果不需要 ...

  6. 【pytest】(十二)参数化测试用例中的setup和teardown要怎么写?

    还是一篇关于pytest的fixture在实际使用场景的分享. fixture我用来最多的就是写setup跟teardown了,那么现在有一个用例是测试一个列表接口,参数化了不同的状态值传参,来进行测 ...

  7. jmeter-并发及常数吞吐量定时器设定

  8. 转 16 jmeter中的监听器以及测试结果分析

    16 jmeter中的监听器以及测试结果分析   常用监听器 断言结果.查看结果树.聚合报告.Summary Report.用表格查看结果.图形结果.aggregate graph等 指标分析 -Sa ...

  9. Fastjson1.2.24反序列化漏洞复现

    Fastjson1.2.24 目录 1. 环境简介 1.1 物理环境 1.2 网络环境 1.3 工具 1.4 流程 2. Docker+vulhub+fastjson1.2.24 2.1 Docker ...

  10. 8.3 Customizing Git - Git Hooks 钩子 自动拉取 自动部署 提交工作流钩子,电子邮件工作流钩子和其他钩子

    https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks https://github.com/git/git/blob/master/temp ...