题目1 : 近期公共祖先·二

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

描写叙述

上上回说到,小Hi和小Ho用很拙劣——或者说粗糙的手段山寨出了一个奇妙的站点,这个站点能够计算出某两个人的全部共同祖先中辈分最低的一个是谁。

远在美国的他们利用了一些奇异的技术获得了国内很多人的相关信息,而且搭建了一个小小的站点来应付来自四面八方的请求。

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

其一是购买更为昂贵的server。通过提高计算机性能的方式来满足需求——但小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的询问,依照在输入中出现的顺序,各输出一行,表示查询的结果:他们的全部共同祖先中辈分最低的一个人的名字。

例子输入
4
Adam Sam
Sam Joey
Sam Micheal
Adam Kevin
3
Sam Sam
Adam Sam
Micheal Kevin
例子输出
Sam
Adam
Adam

离线代码例如以下:

/*************************************************************************
> File Name: t.cpp
> Author: acvcla
> QQ:
> Mail: acvcla@gmail.com
> Created Time: 2014年10月16日 星期四 23时22分13秒
************************************************************************/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cstring>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<cstdlib>
#include<ctime>
#include<set>
#include<math.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 10;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define pb push_back
map<string,int>f1;
map<int,string>f2;
std::vector<int>G[maxn];
map<pair<int,int>,int>ans;
std::vector<int>query[maxn];
int ql[maxn],qr[maxn];
int col[maxn],p[maxn];
int findx(int x){
return p[x]==x? x:p[x]=findx(p[x]);
}
void Union(int u,int v){
p[findx(v)]=findx(u);
}
void Init(int n){
for(int i=0;i<=n;i++){
query[i].clear();
G[i].clear();
col[i]=0;
p[i]=i;
}
f1.clear();
f2.clear();
ans.clear();
}
void lca(int u){
for(int i=0;i<G[u].size();i++){
lca(G[u][i]);
Union(u,G[u][i]);
}
col[u]=1;
for(int i=0;i<query[u].size();++i){
int v=query[u][i];
if(col[v]){
ans[make_pair(u,v)]=findx(v);
}
}
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
int n,m;
while(cin>>n){
string fa,son;
int tot=0;
Init(n+3);
for(int i=1;i<=n;i++){
cin>>fa>>son;
if(!f1[fa]){
f1[fa]=++tot;
f2[tot]=fa;
}if(!f1[son]){
f1[son]=++tot;
f2[tot]=son;
}
//cout<<f1[fa]<<' '<<f1[son]<<endl;
G[f1[fa]].pb(f1[son]);
}
cin>>m;
for(int i=0;i<m;i++){
cin>>fa>>son;
ql[i]=f1[fa];
qr[i]=f1[son];
query[ql[i]].pb(qr[i]);
query[qr[i]].pb(ql[i]);
}
lca(1);
for(int i=0;i<m;i++){
int x=0;
x=ans[make_pair(ql[i],qr[i])];
if(!x)x=ans[make_pair(qr[i],ql[i])];
cout<<f2[x]<<endl;
}
}
return 0;
}

离线LCA学习的更多相关文章

  1. HDU 5044 离线LCA算法

    昨天写了HDU 3966 ,本来这道题是很好解得,结果我想用离线LCA 耍一把,结果发现离线LCA 没理解透,错了好多遍,终得AC ,这题比起 HDU 3966要简单,因为他不用动态查询.但是我还是错 ...

  2. 【图论】tarjan的离线LCA算法

    百度百科 Definition&Solution 对于求树上\(u\)和\(v\)两点的LCA,使用在线倍增可以做到\(O(nlogn)\)的复杂度.在NOIP这种毒瘤卡常比赛中,为了代码的效 ...

  3. HDU 2586 How far away ? 离线lca模板题

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  4. hihoCoder #1067 : 最近公共祖先·二 [ 离线LCA tarjan ]

    传送门: #1067 : 最近公共祖先·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上上回说到,小Hi和小Ho用非常拙劣——或者说粗糙的手段山寨出了一个神奇的网站 ...

  5. poj1470 Closest Common Ancestors [ 离线LCA tarjan ]

    传送门 Closest Common Ancestors Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 14915   Ac ...

  6. SPOJ 10628 Count on a tree(Tarjan离线LCA+主席树求树上第K小)

    COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to  ...

  7. POJ-1330--Nearest Common Ancestors(离线LCA)

    LCA离线算法 它需要一次输入所有的询问,然后有根节点开始进行深度优先遍历(DFS),在深度优先遍历的过程中,进行并查集的操作,同时查询询问,返回结果. 题意: 求A ,B两点的最近公共祖先 分析: ...

  8. 关于Tarjan(3)——离线LCA

    LCA(最近公共祖先),指对于一棵树上任意两个节点往上走最早都能到达的节点. 求LCA有两种方法,一种是倍增,另一种则是Tarjan........ Tarjan巧妙利用并查集的思想: 这里的Tarj ...

  9. HDU 2586.How far away ?-离线LCA(Tarjan)

    2586.How far away ? 这个题以前写过在线LCA(ST)的,HDU2586.How far away ?-在线LCA(ST) 现在贴一个离线Tarjan版的 代码: //A-HDU25 ...

随机推荐

  1. deeplearningbook-chinese

    https://exacity.github.io/deeplearningbook-chinese/

  2. go标准库DOC与 raft

    http://studygolang.com/static/pkgdoc/index.html https://github.com/avelino/awesome-go#database

  3. WCF中的REST是什么

    基于SOAP消息格式的WCF之所以强大原因之一是因为SOAP消息头的高度扩展性.相应的WS-*协议很多都体现在消息头封装的信息上,包括诸如寻址,需要调用方法名,维护Session的信息等等…… SOA ...

  4. 用delphi检查网络连接状态3种方式

    用delphi检查网络连接状态3种方式 用delphi检查网络连接状态 检测计算机是否联网比较简单的做法可以通过一个 Win32 Internet(WinInet) 函数 InternetCheckC ...

  5. 使用FTP发布和更新Windows Azure网站

    在Windows Azure中,FTP的用户名和密码与管理门户的用户名和密码不一样,需要另外设置. →依次点击左侧的"网站",网站名称,右侧的"设置部署凭据", ...

  6. i386、i586、i686、noarch、x86_64

    xxxxxxxxx.rpm   <== RPM的格式,已经经过编译且包装完成的rpm文件. xxxxxx.src.rpm   <== SRPM的格式,包含未编译的源代码信息. 例如rp-p ...

  7. cocos2d-x基本元素

    from://http://www.cnblogs.com/ArmyShen/p/3239664.html 1.CCDirector(导演类) 控制游戏流程的主要类,主要负责设定游戏窗口.切换场景.暂 ...

  8. Android 4.4 Kitkat Phone工作流程浅析(八)__Phone状态分析

    本文来自http://blog.csdn.net/yihongyuelan 转载请务必注明出处 本文代码以MTK平台Android 4.4为分析对象.与Google原生AOSP有些许差异.请读者知悉. ...

  9. Swift - 用UIScrollView实现视差动画效果

    Swift - 用UIScrollView实现视差动画效果 效果 源码 https://github.com/YouXianMing/Swift-Animations // // MoreInfoVi ...

  10. 执行tsung时报"Maximum number of concurrent users in a single VM reached

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://ovcer.blog.51cto.com/1145188/1581326 [roo ...