Skip to content

Commit 306a397

Browse files
authored
Update 6.cpp
1 parent 4324395 commit 306a397

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

Diff for: 21/6.cpp

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#include <bits/stdc++.h>
2+
#define MAX 100001
3+
#define LOG 21 // 2^20 = 1,000,000
4+
5+
using namespace std;
6+
7+
int n, m;
8+
int parent[MAX][LOG]; // 부모에 대한 정보
9+
int d[MAX]; // 각 노드까지의 깊이(depth)
10+
int c[MAX]; // 각 노드의 깊이가 계산되었는지 여부
11+
vector<int> graph[MAX]; // 그래프(graph) 정보
12+
13+
// 루트 노드부터 시작하여 깊이(depth)를 구하는 함수
14+
void dfs(int x, int depth) {
15+
c[x] = true;
16+
d[x] = depth;
17+
for (int i = 0; i < graph[x].size(); i++) {
18+
int y = graph[x][i];
19+
if (c[y]) continue; // 이미 깊이를 구했다면 넘기기
20+
parent[y][0] = x;
21+
dfs(y, depth + 1);
22+
}
23+
}
24+
25+
// 전체 부모 관계를 설정하는 함수
26+
void setParent() {
27+
dfs(1, 0); // 루트 노드는 1번 노드
28+
for (int i = 1; i < LOG; i++) {
29+
for (int j = 1; j <= n; j++) {
30+
parent[j][i] = parent[parent[j][i - 1]][i - 1];
31+
}
32+
}
33+
}
34+
35+
// A와 B의 최소 공통 조상을 찾는 함수
36+
int lca(int a, int b) {
37+
// y가 더 깊도록 설정
38+
if(d[a] > d[b]) {
39+
swap(a, b);
40+
}
41+
// 먼저 깊이(depth)가 동일하도록
42+
for(int i = LOG - 1; i >= 0; i--) {
43+
if(d[b] - d[a] >= (1 << i)) {
44+
b = parent[b][i];
45+
}
46+
}
47+
// 부모가 같아지도록
48+
if(a == b) return a;
49+
for(int i = LOG - 1; i >= 0; i--) {
50+
// 조상을 향해 거슬러 올라가기
51+
if(parent[a][i] != parent[b][i]) {
52+
a = parent[a][i];
53+
b = parent[b][i];
54+
}
55+
}
56+
// 이후에 부모가 찾고자 하는 조상
57+
return parent[a][0];
58+
}
59+
60+
int main() {
61+
scanf("%d", &n);
62+
for (int i = 0; i < n - 1; i++) {
63+
int a, b;
64+
scanf("%d %d", &a, &b);
65+
graph[a].push_back(b);
66+
graph[b].push_back(a);
67+
}
68+
setParent();
69+
70+
cin >> m;
71+
for (int i = 0; i < m; i++) {
72+
int a, b;
73+
scanf("%d %d", &a, &b);
74+
printf("%d\n", lca(a, b));
75+
}
76+
}

0 commit comments

Comments
 (0)