离线LCA学习
题目1 : 近期公共祖先·二
- 例子输入
-
4
Adam Sam
Sam Joey
Sam Micheal
Adam Kevin
3
Sam Sam
Adam Sam
Micheal Kevin - 例子输出
-
Sam
Adam
Adam
描写叙述
上上回说到,小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的询问,依照在输入中出现的顺序,各输出一行,表示查询的结果:他们的全部共同祖先中辈分最低的一个人的名字。
离线代码例如以下:
/*************************************************************************
> 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学习的更多相关文章
- HDU 5044 离线LCA算法
昨天写了HDU 3966 ,本来这道题是很好解得,结果我想用离线LCA 耍一把,结果发现离线LCA 没理解透,错了好多遍,终得AC ,这题比起 HDU 3966要简单,因为他不用动态查询.但是我还是错 ...
- 【图论】tarjan的离线LCA算法
百度百科 Definition&Solution 对于求树上\(u\)和\(v\)两点的LCA,使用在线倍增可以做到\(O(nlogn)\)的复杂度.在NOIP这种毒瘤卡常比赛中,为了代码的效 ...
- HDU 2586 How far away ? 离线lca模板题
How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- hihoCoder #1067 : 最近公共祖先·二 [ 离线LCA tarjan ]
传送门: #1067 : 最近公共祖先·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上上回说到,小Hi和小Ho用非常拙劣——或者说粗糙的手段山寨出了一个神奇的网站 ...
- poj1470 Closest Common Ancestors [ 离线LCA tarjan ]
传送门 Closest Common Ancestors Time Limit: 2000MS Memory Limit: 10000K Total Submissions: 14915 Ac ...
- 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 ...
- POJ-1330--Nearest Common Ancestors(离线LCA)
LCA离线算法 它需要一次输入所有的询问,然后有根节点开始进行深度优先遍历(DFS),在深度优先遍历的过程中,进行并查集的操作,同时查询询问,返回结果. 题意: 求A ,B两点的最近公共祖先 分析: ...
- 关于Tarjan(3)——离线LCA
LCA(最近公共祖先),指对于一棵树上任意两个节点往上走最早都能到达的节点. 求LCA有两种方法,一种是倍增,另一种则是Tarjan........ Tarjan巧妙利用并查集的思想: 这里的Tarj ...
- HDU 2586.How far away ?-离线LCA(Tarjan)
2586.How far away ? 这个题以前写过在线LCA(ST)的,HDU2586.How far away ?-在线LCA(ST) 现在贴一个离线Tarjan版的 代码: //A-HDU25 ...
随机推荐
- hdu 2546 饭卡(背包)
设饭卡余额为total 此题经分析 可以得出:要求选出一些饭菜 时消费量尽量接近total-5元 然后再买一个饭菜 以达到透支... 可以证明 最后买的那个饭菜是饭菜中价值最大的. 证明 设a1 ...
- CreateJs入门必知必会
CreateJS介绍 CreateJS是基于HTML5开发的一套模块化的库和工具.基于这些库,可以非常快捷地开发出基于HTML5的游戏.动画和交互应用.CreateJS主要包含如下四个类库: Ease ...
- AngularJS自定义Directive不一定返回对象
AngularJS中,当需要自定义Directive时,通常返回一个对象,就像如下的写法: angular.module('modulename') .directive('myDirective', ...
- sql语句练习题
6.Mysql不要用top用limit 在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢? 查找时Mysql不能用top,反正我用不了,查了下可以用limit来替换. 比 ...
- GPG入门教程
原文地址:http://www.ruanyifeng.com/blog/2013/07/gpg.html 作者: 阮一峰 日期: 2013年7月12日 前两篇文章,我介绍了RSA算法. 今天,就接着来 ...
- NSURLRequest with UserAgent
关于iOS上的http请求还在不断学习,从早先的时候发现原来iOS的http请求可以自动保存cookie到后来的,发现ASIHttpRequest会有User-Agent,到现在发现竟然NSURLRe ...
- 分享一段ios数据库代码,包括对表的创建、升级、增删查改
分享一段ios数据库代码.包括创建.升级.增删查改. 里面的那些类不必细究,主要是数据库的代码100%可用. 数据库升级部分,使用switch,没有break,低版本一次向高版本修改. // DB.h ...
- iOS webservice 接口使用方法
1.没有参数的webservice 接口,如下: 接口名:获取服务器时间 方法名: getServerTime() 参数:空 返回值:服务器当前时间: yyyy/MM/dd HH:mm:ss 使用方法 ...
- epoll的两种工作模式
epoll有两种模式,Edge Triggered(简称ET) 和 Level Triggered(简称LT).在採用这两种模式时要注意的是,假设採用ET模式,那么仅当状态发生变化时才会通知,而採用L ...
- mongodb centos7上的安装
1,下载安装包 下载mongoDB的安装文件地址:https://www.mongodb.org/downloads#production 选择Linux 64-bit legacy 版本,下载到目标 ...