카테고리 없음
백준 11437번 LCA (JAVA)
박카스마시며코딩
2022. 1. 12. 19:16
https://www.acmicpc.net/problem/11437
11437번: LCA
첫째 줄에 노드의 개수 N이 주어지고, 다음 N-1개 줄에는 트리 상에서 연결된 두 정점이 주어진다. 그 다음 줄에는 가장 가까운 공통 조상을 알고싶은 쌍의 개수 M이 주어지고, 다음 M개 줄에는 정
www.acmicpc.net
해당 문제는 LCA알고리즘을 이용하여 문제를 해결하였습니다.
LCA알고리즘을 사용하려면 먼저 노드들을 depth와 parent로 표시해야합니다.
LCA 로직은 다음과 같습니다.
1. 깊이가 더 깊은 노드를 더 낮은 노드까지 올려줍니다.
2. 두 정점의 깊이가 같아졌으면 각각의 노드가 같은지 확인하고 같다면 해당 노드를 출력하고 다르면 조상을 올려다보며 조상이 같아질 때까지 노드를 타고 올라간다.
여기서 두 정점의 깊이가 같아졌을 때 둘이 같은지를 확인하는 이유는 1번으로인해 두 정점의 깊이가 같아졌을때 둘의 정점이 같아져 현재 정점이 최소 공통 조상이 되는 경우가 존재하기 때문입니다.
package BOJ.LCA;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.StringTokenizer;
import java.util.function.Function;
public class BOJ_11437 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine()," ");
Function<String,Integer> stoi = Integer::parseInt;
int n = stoi.apply(st.nextToken());
List<Integer>[] map = new ArrayList[n+1];
int[] parent = new int[n+1];
int[] depth = new int[n+1];
for(int i = 0 ; i <= n ; i++){
map[i] = new ArrayList<>();
}
for(int i = 0 ; i < n-1 ; i++){
st = new StringTokenizer(br.readLine()," ");
int a = stoi.apply(st.nextToken());
int b = stoi.apply(st.nextToken());
map[a].add(b);
map[b].add(a);
}
Arrays.fill(parent,-1);
parent[1] = 0;
findParent(map,parent,depth,1,n);
// System.out.println(Arrays.toString(parent));
int m = stoi.apply(br.readLine());
for(int i = 0 ; i < m ; i++){
st = new StringTokenizer(br.readLine()," ");
int a = stoi.apply(st.nextToken());
int b = stoi.apply(st.nextToken());
System.out.println(lca(parent,depth,a,b));
}
}
private static void findParent(List<Integer>[] map, int[] parent, int[] depth,int now,int n) {
for(int i = 0 ; i < map[now].size() ; i++){
int next = map[now].get(i);
if(parent[next] == -1){
depth[next] = depth[now] + 1;
parent[next] = now;
findParent(map,parent,depth,next,n);
}
}
}
// private static int lca(int[] parent,int[] depth,int a, int b) {
// while(true){
// if(a == b){
// return a;
// }else if(depth[a] < depth[b]){
// b = parent[b];
// }else if(depth[a] > depth[b]){
// a = parent[a];
// }else {
// if(parent[a] == parent[b]){
// return parent[a];
// }else{
// a = parent[a];
// b = parent[b];
// }
// }
// }
// }
private static int lca(int[] parent,int[] depth,int a, int b) {
if(a == b){
return a;
}else if(depth[a] < depth[b]){
return lca(parent,depth,a,parent[b]);
}else if(depth[a] > depth[b]){
return lca(parent,depth,parent[a],b);
}else {
if(parent[a] == parent[b]){
return parent[a];
}else{
return lca(parent,depth,parent[a],parent[b]);
}
}
}
}