HDU5732 Subway【树重心 树哈希】
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【树重心 树哈希】的更多相关文章
- B+树索引和哈希索引的区别——我在想全文搜索引擎为啥不用hash索引而非得使用B+呢?
哈希文件也称为散列文件,是利用哈希存储方式组织的文件,亦称为直接存取文件.它类似于哈希表,即根据文件中关键字的特点,设计一个哈希函数和处理冲突的方法,将记录哈希到存储设备上. 在哈希文件中,是使用一个 ...
- MySQL B+树索引和哈希索引的区别
导读 在MySQL里常用的索引数据结构有B+树索引和哈希索引两种,我们来看下这两种索引数据结构的区别及其不同的应用建议. 二者区别 备注:先说下,在MySQL文档里,实际上是把B+树索引写成了BT ...
- B+树索引和哈希索引的区别[转]
导读 在MySQL里常用的索引数据结构有B+树索引和哈希索引两种,我们来看下这两种索引数据结构的区别及其不同的应用建议. 二者区别 备注:先说下,在MySQL文档里,实际上是把B+树索引写成了BTRE ...
- MySQL B+树索引和哈希索引的区别(转 JD二面)
导读 在MySQL里常用的索引数据结构有B+树索引和哈希索引两种,我们来看下这两种索引数据结构的区别及其不同的应用建议. 二者区别 备注:先说下,在MySQL文档里,实际上是把B+树索引写成了BTRE ...
- Atitit 常见的树形结构 红黑树 二叉树 B树 B+树 Trie树 attilax理解与总结
Atitit 常见的树形结构 红黑树 二叉树 B树 B+树 Trie树 attilax理解与总结 1.1. 树形结构-- 一对多的关系1 1.2. 树的相关术语: 1 1.3. 常见的树形结构 ...
- 字典树(Trie树)的实现及应用
>>字典树的概念 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树.与二叉查找树不同,Trie树的 ...
- 【Todo】字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树
另开一文分析字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树. 先来一个汇总, 算法: 本文中提到的字符串匹配算法有:KMP, BM, Horspool, Sunday, BF, ...
- 【bzoj1901】dynamic ranking(带修改主席树/树套树)
题面地址(权限题) 不用权限题的地址 首先说说怎么搞带修改主席树? 回忆一般的kth问题,我们的主席树求的是前缀和,这样我们在目标区间的左右端点的主席树差分下就能求出kth. 那么我们如何支持修改操作 ...
- 字典树 trie树 学习
一字典树 字典树,又称单词查找树,Trie树,是一种树形结构,哈希表的一个变种 二.性质 根节点不包含字符,除根节点以外的每一个节点都只包含一个字符: 从根节点到某一节点,路径上经过的字符串连接起 ...
随机推荐
- 详解线程池的作用及Java中如何使用线程池
服务端应用程序(如数据库和 Web 服务器)需要处理来自客户端的高并发.耗时较短的请求任务,所以频繁的创建处理这些请求的所需要的线程就是一个非常消耗资源的操作.常规的方法是针对一个新的请求创建一个新线 ...
- 跨域的几种方式以及call(),apply() bind()方法的作用和区别
jsonp: jsonp 全称是JSON with Padding,是为了解决跨域请求资源而产生的解决方案,是一种依靠开发人员创造出的一种非官方跨域数据交互协议. 一个是描述信息的格式,一个是信息传递 ...
- Nginx 实现动态负载均衡(Nginx-1.10.1 + Consul v0.6.4)
一直也没有找到合适的类似Socat + Haproxy 的组合能用在Nginx,后来发现了Nginx的几个模块,但是也存在各种不足. 而且Nginx 在大流量的情况下nginx -s reload 是 ...
- python模块详解 | progressbar
参考官方文档:https://pypi.org/project/progressbar/#description progressbar 安装: pip install progressbar pro ...
- P1140 相似基因(字符串距离,递推)
题目链接: https://www.luogu.org/problemnew/show/P1140 题目背景 大家都知道,基因可以看作一个碱基对序列.它包含了44种核苷酸,简记作A,C,G,TA,C, ...
- ctfhub技能树—RCE—命令注入
打开靶机 查看页面信息 输入127.0.0.1进行测试 构造payload 127.0.0.1&ls 查看文件内容信息 127.0.0.1 & cat 179852221619745. ...
- Windows安全加固
Windows安全加固 # 账户管理和认证授权 # 1.1 账户 # 默认账户安全 # 禁用Guest账户. 禁用或删除其他无用账户(建议先禁用账户三个月,待确认没有问题后删除.) 操作步骤 本地用户 ...
- 入门OJ:扫雪
扫雪1 题目描述 大雪履盖了整个城市,市政府要求冬季服务部门尽快将一些街道(列在一份清单中)的积雪清除掉以恢复交通,整个城市由许多交叉路口和街道构成,当然任意两个交叉路口都是直接或间接连通的,清单给出 ...
- 目标检测的评价指标(TP、TN、FP、FN、Precision、Recall、IoU、mIoU、AP、mAP)
1. TP TN FP FN GroundTruth 预测结果 TP(True Positives): 真的正样本 = [正样本 被正确分为 正样本] TN(True Negatives): 真的 ...
- IPC图像处理项目流程图
网络摄像机IPC图像处理项目流程图: