博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hihoCoder #1067 : 最近公共祖先·二 [ 离线LCA tarjan ]
阅读量:7212 次
发布时间:2019-06-29

本文共 2971 字,大约阅读时间需要 9 分钟。

#1067 : 最近公共祖先·二

时间限制:
10000ms
单点时限:
1000ms
内存限制:
256MB

描述

上上回说到,小Hi和小Ho用非常拙劣——或者说粗糙的手段山寨出了一个神奇的网站,这个网站可以计算出某两个人的所有共同祖先中辈分最低的一个是谁。远在美国的他们利用了一些奇妙的技术获得了国内许多人的相关信息,并且搭建了一个小小的网站来应付来自四面八方的请求。

但正如我们所能想象到的……这样一个简单的算法并不能支撑住非常大的访问量,所以摆在小Hi和小Ho面前的无非两种选择:

其一是购买更为昂贵的服务器,通过提高计算机性能的方式来满足需求——但小Hi和小Ho并没有那么多的钱;其二则是改进他们的算法,通过提高计算机性能的利用率来满足需求——这个主意似乎听起来更加靠谱。

于是为了他们第一个在线产品的顺利运作,小Hi决定对小Ho进行紧急训练——好好的修改一番他们的算法。

而为了更好的向小Ho讲述这个问题,小Hi将这个问题抽象成了这个样子:假设现小Ho现在知道了N对父子关系——父亲和儿子的名字,并且这N对父子关系中涉及的所有人都拥有一个共同的祖先(这个祖先出现在这N对父子关系中),他需要对于小Hi的若干次提问——每次提问为两个人的名字(这两个人的名字在之前的父子关系中出现过),告诉小Hi这两个人的所有共同祖先中辈分最低的一个是谁?

输入

每个测试点(输入文件)有且仅有一组测试数据。

每组测试数据的第1行为一个整数N,意义如前文所述。

每组测试数据的第2~N+1行,每行分别描述一对父子关系,其中第i+1行为两个由大小写字母组成的字符串Father_i, Son_i,分别表示父亲的名字和儿子的名字。

每组测试数据的第N+2行为一个整数M,表示小Hi总共询问的次数。

每组测试数据的第N+3~N+M+2行,每行分别描述一个询问,其中第N+i+2行为两个由大小写字母组成的字符串Name1_i, Name2_i,分别表示小Hi询问中的两个名字。

对于100%的数据,满足N<=10^5,M<=10^5, 且数据中所有涉及的人物中不存在两个名字相同的人(即姓名唯一的确定了一个人),所有询问中出现过的名字均在之前所描述的N对父子关系中出现过,第一个出现的名字所确定的人是其他所有人的公共祖先

输出

对于每组测试数据,对于每个小Hi的询问,按照在输入中出现的顺序,各输出一行,表示查询的结果:他们的所有共同祖先中辈分最低的一个人的名字。

样例输入
4Adam SamSam JoeySam MichealAdam Kevin3Sam SamAdam SamMicheal Kevin
样例输出
SamAdamAdam

题解:

离线LCA, tarjan

tarjan算法的步骤是(当dfs到节点u时):

1. 在并查集中建立仅有u的集合,设置该集合的祖先为u
2. 对u的每个孩子v:
   2.1 tarjan之
   2.2 合并v到父节点u的集合,确保集合的祖先是u
3. 设置u为已遍历
4. 处理关于u的查询,若查询(u,v)中的v已遍历过,则LCA(u,v)=v所在的集合的祖先      

 

 

结果:Accepted      提交时间:2015-05-15 16:17:22

 

1067 最近公共祖先·二 AC G++ 800ms 35MB 1分钟前
1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 11 #define ll long long 12 13 using namespace std; 14 15 const int N = 100005; 16 const int M = 105; 17 const ll mod = 1000000007; 18 19 int n,m; 20 int tot; 21 map
mp; 22 int f[N]; 23 char s1[N],s2[N]; 24 vector
G[N]; 25 int vis[N]; 26 27 struct PP 28 { 29 int next; 30 int index; 31 PP(int tn,int ti) 32 { 33 next = tn; 34 index = ti; 35 } 36 }; 37 38 vector
query[N]; 39 40 string name[N]; 41 string ans[N]; 42 43 int find(int x) 44 { 45 return f[x] == x ? f[x] : f[x] = find(f[x]); 46 } 47 48 void merge(int x,int y) 49 { 50 int a=find(x); 51 int b=find(y); 52 if(a==b) return; 53 f[b]=a; 54 } 55 56 void ini() 57 { 58 tot=0; 59 int i; 60 int x,y; 61 for(i=0;i<=n;i++){ 62 G[i].clear(); 63 query[i].clear(); 64 f[i]=i; 65 } 66 for(i=1;i<=n;i++){ 67 scanf("%s%s",s1,s2); 68 if(mp.count(s1)==0){ 69 tot++; 70 mp[s1]=tot; 71 x=tot; 72 name[tot]=s1; 73 } 74 else{ 75 x=mp[s1]; 76 } 77 if(mp.count(s2)==0){ 78 tot++; 79 mp[s2]=tot; 80 y=tot; 81 name[tot]=s2; 82 } 83 else{ 84 y=mp[s2]; 85 } 86 87 G[x].push_back(y); 88 G[y].push_back(x); 89 } 90 91 scanf("%d",&m); 92 for(i=1;i<=m;i++){ 93 scanf("%s%s",s1,s2); 94 x=mp[s1]; 95 y=mp[s2]; 96 query[x].push_back(PP(y,i)); 97 query[y].push_back(PP(x,i)); 98 } 99 }100 101 void tarjan(int u,int fa)102 {103 int i;104 int v;105 //printf(" u=%d fa=%d\n",u,fa);106 for(i=0;i

 

转载于:https://www.cnblogs.com/njczy2010/p/4506248.html

你可能感兴趣的文章
HDU 1815, POJ 2749 Building roads(2-sat)
查看>>
几个性能测试工具
查看>>
scala 模式匹配详解 1
查看>>
在CentOS6.5上安装Tomcat6
查看>>
Hadoop2.6.0伪分布环境搭建
查看>>
断点续传(代码实现)
查看>>
Stanford机器学习---第五讲. 神经网络的学习 Neural Networks learning
查看>>
我曾经七次鄙视自己的灵魂 卡里.纪伯伦
查看>>
上传RNA-seq数据到NCBI GEO数据库
查看>>
3分钟快速presentation
查看>>
弹出无边框网页的Javscrpt代码
查看>>
C#代码中背后进行的值拷贝
查看>>
事件处理程序的执行上下文
查看>>
现代软件工程讲义 目录
查看>>
android 拨打电话与发送短信
查看>>
ORM内核原理解析之:延迟加载
查看>>
Oracle 默认表空间(default permanent tablespace) 说明
查看>>
jquery 遍历 TextBox 输入框求和,求平均值并判断输入内容是否为数字
查看>>
设计模式之十(外观模式)
查看>>
Dapper的语法应用
查看>>