[hiho 13]最近公共祖先 一

题目描述

由于这个跟后几周是一个系列,这周的做法比较简单。

把第一个人的所有祖先做标记,第二个人向上查找祖先直到找到一个标记过的节点或无法继续为止。

代码其实没什么意思。

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Main {
	private static class Person {
		String name;
		String father;
		boolean tag = false;
		protected Person(String name, String father) {
			this.name = name;
			this.father = father;
		}
	}
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();in.nextLine();
        Map<String, Person> heritage = new HashMap<String, Person>();
        for (int i = 0; i < n; i++) {
        	String line = in.nextLine();
        	String[] people = line.split(" ");
        	String father = people[0];
        	String son = people[1];
        	Person newPerson = new Person(son, father);
        	heritage.remove(son);
        	heritage.put(son, newPerson);
        	if (heritage.get(father) == null) {
        		Person newFather = new Person(father, null);
        		heritage.put(father, newFather);
        	}
        }
        int m = in.nextInt();in.nextLine();
        for (int i = 0; i < m; i++) {
        	String line = in.nextLine();
        	String[] people = line.split(" ");
        	if (people[0].equals(people[1])) {
        		System.out.println(people[0]);
        		continue;
        	}
        	Person p1 = heritage.get(people[0]);
        	Person p2 = heritage.get(people[1]);
        	Person pt = p1;
        	while (p1 != null) {
        		pt.tag = true;
        		if (pt.father == null) {
        			break;
        		} else {
        			pt = heritage.get(pt.father);
        		}
        	}
        	pt = p2;
        	while (pt != null && pt.tag == false) {
        		if (pt.father == null) {
        			break;
        		} else {
        			pt = heritage.get(pt.father);
        		}
        	}
        	if (pt == null || pt.tag == false) {
        		System.out.println(-1);
        	} else {
        		System.out.println(pt.name);
        	}
        	pt = p1;
        	while (p1 != null) {
        		pt.tag = false;
        		if (pt.father == null) {
        			break;
        		} else {
        			pt = heritage.get(pt.father);
        		}
        	}
        }
        heritage.clear();
        in.close();
    }
}

吐槽:A和A的公共祖先是谁?A如果没出现在描述的父子关系中呢?好坑……

时间: 2024-10-13 22:00:42

[hiho 13]最近公共祖先 一的相关文章

[hiho 17]最近公共祖先 三

题目描述 这次是使用在线算法解决这个问题. 两个节点的最近公共祖先就是这两个节点的通路上深度最浅的那个节点. 可以通过一遍深搜把树转成数组:每次经过一个节点(无论是从父节点进入还是从子节点返回)时,把它放入数组.同时要记录每个节点在数组中最后一次出现的位置. 使用RMQ-ST算法预先计算2^k长度区间内深度最浅的节点编号. 对于每次询问,将其转换为两个区间段求解. #include <iostream> #include <algorithm> #include <cstri

[hiho 15]最近公共祖先 二

题目描述 这次使用离线算法来解决最近公共祖先的问题. 离线算法可以一遍 dfs 处理完所有的查询,因而需要把查询全部储存起来. 具体的 dfs 过程是: 所有节点最初标记为白色,第一次经过该节点时,将其染成灰色,第二次经过该节点时(即离开该节点时)将其染成黑色. 在 dfs 的某个状态下,白色代表未访问的节点,黑色代表已经访问完该节点为根整个子树,灰色代表正在访问该节点为根的子树. 可以在每个节点处查询与该节点相关的所有查询,每个查询对应有另一个节点X(可能是自身): 如果X是白色,说明还未访问

Solution: 最近公共祖先&#183;一 [hiho一下 第十三周]

题目1 : 最近公共祖先·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho最近发现了一个神奇的网站!虽然还不够像58同城那样神奇,但这个网站仍然让小Ho乐在其中,但这是为什么呢? “为什么呢?”小Hi如是问道,在他的观察中小Ho已经沉迷这个网站一周之久了,甚至连他心爱的树玩具都弃置一边. “嘿嘿,小Hi,你快过来看!”小Ho招呼道. “你看,在这个对话框里输入我的名字,在另一个对话框里,输入你的名字,再点这个查询按钮,就可以查出来……什么!我们居然有同一个

hiho一下 第十五周——最近公共祖先&#183;二(Trajan,离线LCA)

题目连接 http://hihocoder.com/problemset/problem/1067 题目大意 就是一棵树求任意两个节点的最近公共祖先. 算法描述 在题目的提示里面有比较详细的解释.这里就不多说了.这种算法的时间复杂度是O(n+q). 在算法的实现上也有一些技巧,在参考了一些代码后写了一个比较精简的Trajan_LAC算法. #include <bits/stdc++.h> using namespace std; typedef long long LL; const int

LCA(最近公共祖先)--tarjan离线算法 hdu 2586

HDU 2586 How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11320    Accepted Submission(s): 4119 Problem Description There are n houses in the village and some bidirectional roads c

LeetCode OJ:Lowest Common Ancestor of a Binary Tree(最近公共祖先)

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w

[最近公共祖先] POJ 1330 Nearest Common Ancestors

Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 27316   Accepted: 14052 Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below:  In the figure, eac

数据结构问题集锦 - 最小公共祖先问题

作为一个工程党,在各路竞赛大神的面前总会感到自己实力的捉急.大神总是能够根据问题的不同,轻而易举地给出问题的解法,然而我这种渣渣只能用所谓的”直观方法“聊以自慰,说多了都是泪啊.However,正视自己理论方面的不足,迎头赶上还是必要的,毕竟要真正踏入业界,理论知识是不能少的啊.(比如各种语言的Hash Map,它们的核心可都是红黑树啊) 既然助教要求博文要直观,通俗易懂,那就让我们递归这种方法开始.方法一:递归法 按照题目的要求,如果某两个节点具有同一个公共祖先的话,那么会存在两种情况:要么其

lca 最近公共祖先

http://poj.org/problem?id=1330 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 const int inf=0x3f3f3f3f; 7 class LCA { ///最近公共祖先 build_o(n*logn) query_o(1) 8 t