题目来源:最近公共祖先·一

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

题目描述

小Ho最近发现了一个神奇的网站!虽然还不够像58同城那样神奇,但这个网站仍然让小Ho乐在其中,但这是为什么呢?

“为什么呢?”小Hi如是问道,在他的观察中小Ho已经沉迷这个网站一周之久了,甚至连他心爱的树玩具都弃置一边。

“嘿嘿,小Hi,你快过来看!”小Ho招呼道。

“你看,在这个对话框里输入我的名字,在另一个对话框里,输入你的名字,再点这个查询按钮,就可以查出来……什么!我们居然有同一个祖祖祖祖祖爷爷?”

“诶,真是诶……这个网站有点厉害啊。”小Hi不由感叹道。

“是啊,这是什么算法啊,这么厉害!”小Ho也附和道。

“别2,我说的是他能弄到这些数据很厉害,而人类的繁殖树这种层数比较浅的树对这类算法的要求可是简单的不得了,你都能写出来呢!”小Hi道。

“啊?我也能写出来?可是……该从哪开始呢?”小Ho困惑了。

小Ho要面临的问题是这样的,假设现在他知道了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^2,M<=10^2, 且数据中所有涉及的人物中不存在两个名字相同的人(即姓名唯一的确定了一个人)。

输出

对于每组测试数据,对于每个小Hi的询问,输出一行,表示查询的结果:如果根据已知信息,可以判定询问中的两个人存在共同的祖先,则输出他们的所有共同祖先中辈分最低的一个人的名字,否则输出-1。

样例输入

11
JiaYan JiaDaihua
JiaDaihua JiaFu
JiaDaihua JiaJing
JiaJing JiaZhen
JiaZhen JiaRong
JiaYuan JiaDaishan
JiaDaishan JiaShe
JiaDaishan JiaZheng
JiaShe JiaLian
JiaZheng JiaZhu
JiaZheng JiaBaoyu
3
JiaBaoyu JiaLian
JiaBaoyu JiaZheng
JiaBaoyu LinDaiyu

样例输出

JiaDaishan
JiaZheng
-1

解题思路:首先定义一个Node类,其中name表示节点的名字,isVisited表示该节点是否被访问过,parentIndex表示其父节点在数组中的下标,每当接受一组输入数据(parent,child)时,就在数组中查找该parent节点和child节点是否创建,然后再建立关系,最后整个数组中的数据全部建立了关系。当接收到一对询问(first,second)时,首先将first以及first的祖先节点isVisited设置为true,second也是一样,如果发现当前节点的isVisited已经为true,说明first已经访问过该节点,并且该节点为(first,second)的最近公共子节点。为了加速查找,采用hashmap来记录节点信息。

具体算法(java版,可以直接AC)

 import java.util.HashMap;
import java.util.Scanner; public class Main { private HashMap<String,Integer>nodeMap;
private Node[]nodes;
private int index;
private int ancestorIndex; public Main(){
this.nodeMap=new HashMap<String,Integer>();
this.nodes=new Node[1001];
this.index=0;
this.ancestorIndex=-1;
} private void reset(){
for(int i=0;i<this.index;i++){
this.nodes[i].isVisited=false;
}
this.ancestorIndex=-1;
} private int getNode(String nodeName){
if(!this.nodeMap.containsKey(nodeName)){
this.nodes[this.index]=new Node(nodeName);
this.nodeMap.put(nodeName, this.index);
this.index++;
}
return this.nodeMap.get(nodeName);
} private void visit(int nodeIndex){
if(nodeIndex>=0&&nodeIndex<this.index){
if(this.nodes[nodeIndex].isVisited){
this.ancestorIndex= nodeIndex;
return;
}else{
this.nodes[nodeIndex].isVisited=true;
int parentIndex=this.nodes[nodeIndex].parentIndex;
this.visit(parentIndex);
}
}
} public void addNode(String parent,String child){
int parentIndex=this.getNode(parent);
int childIndex=this.getNode(child);
if(parentIndex>=0&&parentIndex<this.index
&&childIndex>=0&&childIndex<this.index){
this.nodes[childIndex].parentIndex=parentIndex;
}
} public void getAncestor(String first,String second){
int firstIndex=this.getNode(first);
int secondIndex=this.getNode(second);
this.visit(firstIndex);
this.visit(secondIndex);
if(this.ancestorIndex>=0&&this.ancestorIndex<this.index){
this.nodes[this.ancestorIndex].print();
}else{
System.out.println("-1");
}
this.reset();
} public static void main(String[] args) { Scanner scanner=new Scanner(System.in);
Main ancestor=new Main();
int n=scanner.nextInt();
for(int i=0;i<n;i++){
String first=scanner.next();
String second=scanner.next();
ancestor.addNode(first, second);
}
int m=scanner.nextInt();
for(int i=0;i<m;i++){
String first=scanner.next();
String second=scanner.next();
ancestor.getAncestor(first, second);
}
} } class Node{
public String name;
public int parentIndex;
public boolean isVisited;
public Node(String name){
this.name=name;
this.parentIndex=-1;
this.isVisited=false;
}
public void print(){
System.out.println(this.name);
}
}

算法效率不是很好,如果有好的算法可以留言,谢谢!

hihoCoder 1062 最近公共祖先·一 最详细的解题报告的更多相关文章

  1. hihocoder #1062 : 最近公共祖先·一(小数据量 map+set模拟+标记检查 *【模板】思路 )

    #1062 : 最近公共祖先·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho最近发现了一个神奇的网站!虽然还不够像58同城那样神奇,但这个网站仍然让小Ho乐在 ...

  2. hihoCoder#1062(最近公共祖先一)

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho最近发现了一个神奇的网站!虽然还不够像58同城那样神奇,但这个网站仍然让小Ho乐在其中,但这是为什么呢? “为什么呢 ...

  3. hihoCoder#1062 最近公共祖先·

    原题地址 A和A的共同祖先是A,即使A没有在之前的家谱中出现过!被这个坑了,WA了很久... 比如:小头爸爸是大头儿子他爹,问:隔壁王叔叔和隔壁王叔叔的最近祖先是谁?,答:隔壁王叔叔. 代码: #in ...

  4. hiho #1062 : 最近公共祖先·一(树,最近祖先)

    #1062 : 最近公共祖先·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho最近发现了一个神奇的网站!虽然还不够像58同城那样神奇,但这个网站仍然让小Ho乐在 ...

  5. HihoCoder 1067 最近公共祖先(ST离线算法)

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

  6. Hihocoder #1067 : 最近公共祖先·二

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上上回说到,小Hi和小Ho用非常拙劣——或者说粗糙的手段山寨出了一个神奇的网站,这个网站可以计算出某两个人的所有共同祖先中 ...

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

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

  8. hihoCoder week13 最近公共祖先·一

    用的dfs,自下往上搜索一个节点的所有祖先,然后在相应祖先 判断是否是另一个节点的祖先,如果是 就截止,否则继续往上搜索,直到搜索到,或者知道所有的祖先都被扫描完成 #include <bits ...

  9. hihoCoder week17 最近公共祖先·三 lca st表

    记录dfs序列,dfn[tot] 记录第tot次访问的节点 然后查两点在dfs序中出现的第一次 id[u] id[v] 然后  找 dep[k] = min( dep[i] ) {i 属于 [id[u ...

随机推荐

  1. Codeforce Round #643 #645 #646 (Div2)

    codeforce Round #643 #645 #646 div2 Round #643 problem A #include<bits/stdc++.h> using namespa ...

  2. centos7 hive 单机模式安装配置

    前言:由于只是在自己的虚拟机上进行学习,所以对hive只是进行最简单的配置,其他复杂的配置文件没有配置. 1.前提 1.1 安装配置jdk1.8 1.2 安装hadoop2.x hadoop单机模式安 ...

  3. (四)log4j同配置下多个进程写日志

    原文链接:https://blog.csdn.net/voiceofwind/article/details/51966361 由于起了两个不同的任务,log4j中用的是一套配置,写入的是同一个路径, ...

  4. C#基础——IO

    最近一直忙着做项目,偶尔会碰到一些文件读写方面的需求,当我回忆读写的代码时,发现脑子里存在诸多空白.这是不妙的,于是连忙翻出以前记下的笔记,上面还存在着我当初写下的知识点.怕以后哪天笔记找不到了或者有 ...

  5. GoAccess分析Web日志

    简介 为什么要用GoAccess? GoAccess 被设计成快速的并基于终端的日志分析工具.其核心理念是不需要通过 Web 浏览器就能快速分析并实时查看 Web 服务器的统计数据(这对于需要使用 S ...

  6. 连接 mongodb 数据库 :

    mongodb  数据库: 安装 mongodb  数据库: 安装 mongodb 数据库网址: https://www.mongodb.com/download-center#community 检 ...

  7. 深入理解RocketMQ(一)---阅读源码准备

    本文主要描述使用Idea获取rocketMQ源码及源码的读取. 在演示搭建源码环境前,先简要描述一下RocketMQ的设计目标. 1.架构模式 和大多数消息中间件一样,采用的是发布订阅模式,基本组件包 ...

  8. DevOps研发模式下「产品质量度量」方案实践

    在当今互联网环境下,需求变更越来越快,交付周期却越来越短, 怎么判断一个系统是否测试充分? 产品质量满足什么样的条件才能投产? 如何判断测试工作.研发团队工作的效率是高还是低? 这些问题不能靠感觉.拍 ...

  9. oracle数据库插入日期格式字符串给date类型字段

    首先执行 alter session set nls_date_format='yyyy-mm-dd  hh24:mi:ss'; 然后执行insert语句而无需使用to_date函数

  10. 同一WpfApplication下简单的页面转换

    别人写的很不错的Dome...分享学习下 源文件地址 : http://pan.baidu.com/share/link?shareid=1698564707&uk=3912660076