hihocoder 1069最近公共祖先(DFS + ST)java实现

原创 2016年05月30日 16:06:34

package tree;


import java.util.ArrayList;

import java.util.HashMap;

import java.util.Map.Entry;

import java.util.Scanner;


/*

 * 8

adam sam

sam joey

tom lv

tom lee

kevin john

adam kevin

sam peter

sam tom

 */

public class Week17 {


public static void main(String[] args) {

Scanner scanner =new Scanner(System.in);

int datanum = Integer.parseInt(scanner.nextLine());

HashMap<String, ArrayList<String>> DFSmap = new HashMap<String, ArrayList<String>>();

ArrayList<DFSNode17> DFSarrAdep = new ArrayList<DFSNode17>();

HashMap<String, Integer> fAppearMap = new HashMap<String, Integer>();

DFSNode17 [][]ST =new DFSNode17[2*datanum + 2][2*datanum + 2];

String admisssion =null;

for(inti=0; i<datanum;i++){

String data =scanner.nextLine();

String father =data.split(" ")[0];

String son =data.split(" ")[1];

if(i==0)admisssion = father;

Week17.createDFSmap(DFSmap,father, son);

}

Week17.DFS(admisssion, 0,DFSmap, DFSarrAdep,fAppearMap);

Week17.createST(DFSarrAdep,ST);

int querynum = Integer.parseInt(scanner.nextLine());

for(inti=0; i<querynum;i++){

String data =scanner.nextLine();

String p1 =data.split(" ")[0];

String p2 =data.split(" ")[1];

Week17.searchST(p1,p2, ST, fAppearMap);

}

}

public static void createDFSmap(HashMap<String, ArrayList<String>>DFSmap, String father, Stringson){

if(DFSmap.containsKey(father)){

ArrayList<String> temp = DFSmap.get(father);

temp.add(son);

}

else{

ArrayList<String> temp = new ArrayList<String>();

temp.add(son);

DFSmap.put(father,temp);

}

}

public static void DFS(String admisssion, int depth, HashMap<String, ArrayList<String>> DFSmap, ArrayList<DFSNode17>DFSarrAdep, HashMap<String, Integer> fAppearMap){

DFSarrAdep.add(new DFSNode17(admisssion,depth));

if(!fAppearMap.containsKey(admisssion))fAppearMap.put(admisssion,DFSarrAdep.size()-1);

if(DFSmap.containsKey(admisssion)){

ArrayList<String> temp = DFSmap.get(admisssion);

for(inti=0; i<temp.size();i++){

DFS(temp.get(i), ++depth,DFSmap, DFSarrAdep,fAppearMap);

depth--;

DFSarrAdep.add(new DFSNode17(admisssion,depth));

}

}

}

public static void createST(ArrayList<DFSNode17>DFSarrAdep, DFSNode17 [][]ST){

for(inti=1; i<ST[0].length;i*=2){

for(intj=1; j<ST.length;j++){

if(i==1)ST[j][i] =DFSarrAdep.get(j-1);

else{

if(j +i/2 < ST.length){

int depth1 = ST[j][i/2].getDepth();

int depth2 = ST[j +i/2][i/2].getDepth();

ST[j][i] =depth1 > depth2 ?ST[j + i/2][i/2] : ST[j][i/2];

}

else ST[j][i] =ST[j][i/2];

}

}

}

}

public static void searchST(String p1, String p2, DFSNode17 [][]ST, HashMap<String, Integer>fAppearMap){

if(p1.equals(p2)) System.out.println(p1);

else{

intappear1 = fAppearMap.get(p1) + 1;

intappear2 = fAppearMap.get(p2) + 1;

intleft, right;

if(appear1 >appear2){

left =appear2;

right =appear1;

}

else{

left =appear1;

right =appear2;

}

int range = right - left + 1;

int power = 0;

while(range != 0){

range >>= 1;

power++;

}

int depth1 = ST[left][(int)Math.pow(2,power-1)].getDepth();

int depth2 = ST[right - (int)Math.pow(2,power-1) + 1][(int)Math.pow(2,power-1)].getDepth();

String name =depth1 <= depth2 ?ST[left][(int)Math.pow(2,power-1)].getValue() : 

ST[right - (int)Math.pow(2,power-1) + 1][(int)Math.pow(2,power-1)].getValue(); 

System.out.println(name);

}

}

}


class DFSNode17{

private Stringvalue;

privateint depth;

public DFSNode17(Stringvalue, int depth){

this.value =value;

this.depth =depth;

}


public String getValue() {

returnvalue;

}


public void setValue(String value) {

this.value =value;

}


public int getDepth() {

returndepth;

}


public void setDepth(int depth) {

this.depth =depth;

}


}

相关文章推荐

hihoCoder_#1069_最近公共祖先·三(RMQ-ST模板)

分析:LCA的在线算法,RMQ-ST算法。留存作为模板。 从树的根节点开始进行深度优先搜索,每次经过某一个点——无论是从它的父亲节点进入这个点,还是从它的儿子节点返回这个点,都按顺序记录下来。这样,...

hihoCoder 1069 最近公共祖先 在线算法

题意 多组询问,求最近公共祖先 思路 基本思路就是,把节点映射到一个数组的下标中,然后数组记录每个点的深度 我们需要保证,每两个节点映射的位置间,存在只存在它俩的最近公共祖先,而不存在其它祖先 我们先...

hihoCoder 1069 最近公共祖先·三

#include using namespace std; map nameMap; string names[100005]; struct node{ int pa; vector so...

[HihoCoder]#1069 : 最近公共祖先·三

华电北风吹 天津大学认知计算与应用重点实验室 2016-06-24题目链接: http://hihocoder.com/problemset/problem/1062题目分析: // pr...

hihoCoder1067 最近公共祖先离线查询 dfs + 并查集

题意 给定树,有q个查询,查询点对的最近公共祖先 思路 课参考题中给的解析:http://hihocoder.com/problemset/problem/1067 实现#include using...

[hiho]#1069 : 最近公共祖先·三 线段树|树转数组

描述:(原题地址:http://hihocoder.com/problemset/problem/1069?sid=601396) 给定一颗树,给出树根,以及一些查询pair,要求输出每条查询pai...

hiho 17 最近公共祖先(三) 转换为区间最值查找 ST

问题描述描述上上回说到,小Hi和小Ho使用了Tarjan算法来优化了他们的“最近公共祖先”网站,但是很快这样一个离线算法就出现了问题:如果只有一个人提出了询问,那么小Hi和小Ho很难决定到底是针对这个...

【算法】最近公共祖先之在线算法(RMQ-ST)

在线算法是基于RMQ-ST算法的基础上进行的RMQ问题求解算法给定一个整型数组,长度为n,寻找区间内的极值,m表示询问的次数。求解算法不外乎下面两种: 1、最基础的算法就是每次都遍历一次区间则时间复...

最近公共祖先(LCA)问题-在线ST算法

LCA算法详解1. 概述LCA(Least Common Ancestors),即最近公共祖先,是指这样一个问题:在有根树中,找出某两个结点u和v最近的公共祖先(另一种说法,离树根最远的公共祖先)。对...

hihocoder第十三周最近公共祖先

最近公共祖先结点
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hihocoder 1069最近公共祖先(DFS + ST)java实现
举报原因:
原因补充:

(最多只允许输入30个字)