Skip to content

Commit 71e70b8

Browse files
committed
[Platinum V] Title: LCA 2, Time: 1648 ms, Memory: 100032 KB -BaekjoonHub
1 parent 0344857 commit 71e70b8

File tree

2 files changed

+135
-0
lines changed

2 files changed

+135
-0
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import java.util.*;
2+
import java.io.*;
3+
4+
public class Main {
5+
static int N, M;
6+
static ArrayList<Integer>[] tree;
7+
static boolean[] visited;
8+
static int[][] parent;
9+
static int[] depth;
10+
static int kMax = 0;
11+
12+
public static void main(String[] args) throws IOException {
13+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
14+
StringTokenizer st;
15+
16+
// 초기화
17+
N = Integer.parseInt(br.readLine());
18+
tree = new ArrayList[N+1];
19+
for(int i=0; i<=N; i++) {
20+
tree[i] = new ArrayList<>();
21+
}
22+
23+
// 입력
24+
for(int i=0; i<N-1; i++) {
25+
st = new StringTokenizer(br.readLine());
26+
int s = Integer.parseInt(st.nextToken());
27+
int e = Integer.parseInt(st.nextToken());
28+
tree[s].add(e);
29+
tree[e].add(s);
30+
}
31+
32+
// bfs용 변수 초기화
33+
depth = new int[N+1];
34+
visited = new boolean[N+1];
35+
int temp = 1;
36+
while(temp <= N) {
37+
temp *= 2;
38+
kMax++;
39+
}
40+
41+
// parent
42+
parent = new int[kMax+1][N+1];
43+
BFS(1);
44+
for(int k=1; k<=kMax; k++) {
45+
for(int n=1; n<=N; n++) {
46+
parent[k][n] = parent[k-1][parent[k-1][n]];
47+
}
48+
}
49+
50+
// 질의
51+
M = Integer.parseInt(br.readLine());
52+
for(int i=0; i<M; i++) {
53+
st = new StringTokenizer(br.readLine());
54+
int a = Integer.parseInt(st.nextToken());
55+
int b = Integer.parseInt(st.nextToken());
56+
System.out.println(LCA(a,b));
57+
}
58+
}
59+
60+
static int LCA(int a, int b ) {
61+
if(depth[a] > depth[b]) {
62+
int temp = a;
63+
a = b;
64+
b = temp;
65+
}
66+
67+
// depth 맞추기
68+
for(int k=kMax; k>=0; k--) {
69+
if(Math.pow(2,k) <= depth[b] - depth[a]) {
70+
if(depth[a] <= depth[parent[k][b]]) {
71+
b = parent[k][b];
72+
}
73+
}
74+
}
75+
76+
// 조상 찾기
77+
for(int k=kMax; k>=0; k--) {
78+
if(parent[k][a] != parent[k][b]) {
79+
a = parent[k][a];
80+
b = parent[k][b];
81+
}
82+
}
83+
84+
return a!=b ? parent[0][a] : a;
85+
}
86+
87+
static void BFS(int root) {
88+
Queue<Integer> q = new LinkedList<>();
89+
q.add(root);
90+
visited[root] = true;
91+
depth[root] = 0;
92+
93+
while(!q.isEmpty()) {
94+
int now = q.poll();
95+
for(int next : tree[now]) {
96+
if(!visited[next]) {
97+
q.add(next);
98+
visited[next] = true;
99+
parent[0][next] = now; // 부모 노드 저장
100+
depth[next] = depth[now] + 1;
101+
}
102+
}
103+
}
104+
}
105+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# [Platinum V] LCA 2 - 11438
2+
3+
[문제 링크](https://www.acmicpc.net/problem/11438)
4+
5+
### 성능 요약
6+
7+
메모리: 100032 KB, 시간: 1648 ms
8+
9+
### 분류
10+
11+
자료 구조, 트리, 최소 공통 조상, 희소 배열
12+
13+
### 제출 일자
14+
15+
2026년 3월 3일 14:51:38
16+
17+
### 문제 설명
18+
19+
<p>N(2 ≤ N ≤ 100,000)개의 정점으로 이루어진 트리가 주어진다. 트리의 각 정점은 1번부터 N번까지 번호가 매겨져 있으며, 루트는 1번이다.</p>
20+
21+
<p>두 노드의 쌍 M(1 ≤ M ≤ 100,000)개가 주어졌을 때, 두 노드의 가장 가까운 공통 조상이 몇 번인지 출력한다.</p>
22+
23+
### 입력
24+
25+
<p>첫째 줄에 노드의 개수 N이 주어지고, 다음 N-1개 줄에는 트리 상에서 연결된 두 정점이 주어진다. 그 다음 줄에는 가장 가까운 공통 조상을 알고싶은 쌍의 개수 M이 주어지고, 다음 M개 줄에는 정점 쌍이 주어진다.</p>
26+
27+
### 출력
28+
29+
<p>M개의 줄에 차례대로 입력받은 두 정점의 가장 가까운 공통 조상을 출력한다.</p>
30+

0 commit comments

Comments
 (0)