Skip to content

Commit 43545df

Browse files
authored
Merge pull request #4 from AlgorithmWithGod/ShinHeeEul
[20250203] BOJ / P5 / LCA2 / 신희을
2 parents df235e8 + 2143f2c commit 43545df

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
```java
2+
import java.io.*;
3+
import java.util.*;
4+
5+
public class Solution {
6+
7+
static List<Integer>[] lists;
8+
static int[][] parents;
9+
static int[] depths;
10+
static int N;
11+
static Queue<Integer> update = new LinkedList<>();
12+
13+
public static void main(String[] args) throws Exception{
14+
// LCA
15+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
16+
17+
// 전처리
18+
19+
N = Integer.parseInt(br.readLine());
20+
lists = new ArrayList[N + 1];
21+
parents = new int[N + 1][17];
22+
depths = new int[N + 1];
23+
24+
for(int i = 0; i < N + 1; i++) {
25+
lists[i] = new ArrayList<>();
26+
}
27+
28+
// 내려가면서 tree 만들어
29+
for(int i = 1; i < N; i++) {
30+
StringTokenizer st = new StringTokenizer(br.readLine());
31+
int a = Integer.parseInt(st.nextToken());
32+
int b = Integer.parseInt(st.nextToken());
33+
lists[a].add(b);
34+
lists[b].add(a);
35+
}
36+
37+
//자식 트리 생성
38+
dfs();
39+
// 2^k Parent 배열 만들어
40+
// 2^k+1 번째 부모는 2^k번째 부모의 2^k번째 부모
41+
// parent[i][j + 1] = parent[parent[i][j]][j];
42+
43+
while(!update.isEmpty()) {
44+
int i = update.poll();
45+
for(int j = 0; j < 16; j++) parents[i][j + 1] = parents[parents[i][j]][j];
46+
}
47+
48+
49+
int M = Integer.parseInt(br.readLine());
50+
51+
StringBuilder sb = new StringBuilder();
52+
for(int m = 0; m < M; m++) {
53+
StringTokenizer st = new StringTokenizer(br.readLine());
54+
55+
int a = Integer.parseInt(st.nextToken());
56+
int b = Integer.parseInt(st.nextToken());
57+
58+
// 뎊스 차이만큼 올라가 (뎊스를 맞춰)
59+
int depthA = depths[a];
60+
int depthB = depths[b];
61+
62+
if(depthA > depthB) {
63+
a = calculateDiff(a, depthA - depthB);
64+
} else {
65+
b = calculateDiff(b, depthB - depthA);
66+
}
67+
68+
// 2^k 만큼 올라가면서 부모 찾아
69+
// 일치 하지 않아? 또 올라가
70+
// 일치해? 내려가
71+
72+
for(int i = 16; i >= 0; i--) {
73+
int pa = parents[a][i];
74+
int pb = parents[b][i];
75+
76+
if(pa != pb) {
77+
a = pa;
78+
b = pb;
79+
i++;
80+
}
81+
}
82+
if(a == b) sb.append(a).append("\n");
83+
else sb.append(parents[a][0]).append("\n");
84+
}
85+
86+
System.out.println(sb);
87+
88+
89+
}
90+
91+
public static int calculateDiff(int val, int diff) {
92+
for(int i = 0; diff >= (1 << i); i++) {
93+
int binary = 1 << i;
94+
if((binary | diff) == diff) {
95+
val = parents[val][i];
96+
}
97+
}
98+
99+
return val;
100+
}
101+
102+
public static void dfs() {
103+
Stack<Node> stack = new Stack<>();
104+
boolean[] visited = new boolean[N + 1];
105+
106+
stack.add(new Node(1, 1));
107+
visited[1] = true;
108+
update.add(1);
109+
110+
while(!stack.isEmpty()) {
111+
Node node = stack.pop();
112+
113+
int parent = node.val;
114+
int depth = node.depth;
115+
depths[parent] = depth;
116+
update.add(parent);
117+
118+
for(int a : lists[parent]) {
119+
if(visited[a]) {
120+
parents[parent][0] = a;
121+
continue;
122+
}
123+
visited[a] = true;
124+
stack.push(new Node(a, depth + 1));
125+
}
126+
}
127+
}
128+
129+
public static class Node {
130+
int val;
131+
int depth;
132+
133+
public Node(int val, int depth) {
134+
this.val = val;
135+
this.depth = depth;
136+
}
137+
}
138+
139+
}
140+
```

0 commit comments

Comments
 (0)