Skip to content

Commit 8a24745

Browse files
authored
Merge pull request #238 from AlgorithmWithGod/ShinHeeEul
[20250313] BOJ / P2 / LCA와 쿼리 / 신희을
2 parents c0e5547 + 6827562 commit 8a24745

File tree

1 file changed

+179
-0
lines changed

1 file changed

+179
-0
lines changed
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
```java
2+
import java.io.*;
3+
import java.util.*;
4+
5+
public class Main {
6+
7+
8+
static ArrayList<Integer>[] lists;
9+
10+
static int[][] parents;
11+
static boolean[] visited;
12+
static int[] depths;
13+
static int logN;
14+
15+
public static void main(String[] args) throws Exception {
16+
// TODO Auto-generated method stub
17+
18+
int N = read();
19+
20+
lists = new ArrayList[N + 1];
21+
visited = new boolean[N + 1];
22+
depths = new int[N + 1];
23+
logN = (int) (Math.log(N) / Math.log(2));
24+
parents = new int[N + 1][logN + 1];
25+
26+
for(int i = 0; i <= N; i++) {
27+
lists[i] = new ArrayList<>();
28+
}
29+
30+
// 트리 만들고
31+
for(int i = 1; i < N; i++) {
32+
33+
int a = read();
34+
int b = read();
35+
36+
lists[a].add(b);
37+
lists[b].add(a);
38+
}
39+
40+
visited = new boolean[N + 1];
41+
parents = new int[N + 1][logN + 1];
42+
43+
// dfs
44+
dfs();
45+
46+
// parents 배열 만들기
47+
for(int i = 1; i <= logN; i++) {
48+
for(int j = 2; j <= N; j++) {
49+
parents[j][i] = parents[parents[j][i-1]][i-1];
50+
}
51+
}
52+
53+
int M = read();
54+
StringBuilder sb = new StringBuilder();
55+
56+
for(int i = 0; i < M; i++) {
57+
58+
int r = read();
59+
int u = read();
60+
int v = read();
61+
62+
// depths 높이 맞추기
63+
64+
// lca 3번
65+
int mr = lca(r, u);
66+
int mu = lca(r, v);
67+
int mv = lca(u, v);
68+
69+
70+
int ans = mr;
71+
if(depths[ans] < depths[mu]) {
72+
ans = mu;
73+
}
74+
if(depths[ans] < depths[mv]) {
75+
ans = mv;
76+
}
77+
sb.append(ans).append("\n");
78+
79+
}
80+
81+
System.out.println(sb);
82+
83+
}
84+
85+
public static int lca(int a, int b) {
86+
87+
int depthA = depths[a];
88+
int depthB = depths[b];
89+
90+
91+
if(depthA < depthB) {
92+
b = diff(b, depthB - depthA);
93+
} else {
94+
a = diff(a, depthA - depthB);
95+
}
96+
97+
if(a == b) return a;
98+
99+
100+
for(int i = logN; i >= 0; i--) {
101+
102+
int aa = parents[a][i];
103+
int bb = parents[b][i];
104+
105+
if(aa == bb) continue;
106+
107+
108+
a = aa;
109+
b = bb;
110+
}
111+
112+
if(a == b) return a;
113+
114+
return parents[a][0];
115+
}
116+
117+
public static int diff(int a, int diff) {
118+
119+
for(int i = 0; (1 << i) <= diff ; i++) {
120+
int de = (1 << i);
121+
122+
if((de | diff) == diff) {
123+
a = parents[a][i];
124+
}
125+
}
126+
127+
return a;
128+
}
129+
130+
public static void dfs() {
131+
132+
Stack<Node> stack = new Stack<>();
133+
stack.add(new Node(1, 1));
134+
visited[1] = true;
135+
while(!stack.isEmpty()) {
136+
Node node = stack.pop();
137+
int val = node.val;
138+
int depth = node.depth;
139+
depths[val] = depth;
140+
for(int nxt : lists[val]) {
141+
if(visited[nxt]) continue;
142+
visited[nxt] = true;
143+
parents[nxt][0] = val;
144+
145+
stack.add(new Node(nxt, depth + 1));
146+
}
147+
148+
}
149+
}
150+
151+
public static class Node implements Comparable<Node> {
152+
int depth;
153+
int val;
154+
155+
Node(int val, int depth) {
156+
this.depth = depth;
157+
this.val = val;
158+
}
159+
160+
public int compareTo(Node o) {
161+
return this.depth - o.depth;
162+
}
163+
}
164+
165+
private static int read() throws Exception {
166+
int d, o;
167+
d = System.in.read();
168+
169+
170+
o = d & 15;
171+
while ((d = System.in.read()) > 32)
172+
o = (o << 3) + (o << 1) + (d & 15);
173+
174+
return o;
175+
}
176+
177+
178+
}
179+
```

0 commit comments

Comments
 (0)