https://www.acmicpc.net/problem/11437
11437번: LCA
첫째 줄에 노드의 개수 N이 주어지고, 다음 N-1개 줄에는 트리 상에서 연결된 두 정점이 주어진다. 그 다음 줄에는 가장 가까운 공통 조상을 알고싶은 쌍의 개수 M이 주어지고, 다음 M개 줄에는 정
www.acmicpc.net
이전 포스트를 참고하였다면 쉽게 풀 수 있는 문제이다.
n 제한이 50000이라서 높이를 최대 16(2^16 = 65536)으로 주었다.
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int>> v;
int n, depth[50001], parent[50001][17];
void dfs(int pre, int node, int h) {
depth[node] = h;
for (auto& i : v[node]) {
if (i != pre) {
parent[i][0] = node;
dfs(node, i, h + 1);
}
}
}
int getA(int a, int b) {
if (depth[a] != depth[b]) {
if (depth[a] > depth[b]) {
swap(a, b);
}
for (int i = 16; i >= 0; i--) {
if (parent[b][i] == 0) continue;
if (depth[a] <= depth[parent[b][i]]) {
b = parent[b][i];
}
}
}
int ret = a;
if (a != b) {
for (int i = 16; i >= 0; i--) {
if (parent[a][i] != parent[b][i]) {
a = parent[a][i];
b = parent[b][i];
}
ret = parent[a][i];
}
}
return ret;
}
int main() {
cin >> n;
v.resize(n + 1);
for (int i = 0; i < n - 1; i++) {
int a, b;
cin >> a >> b;
v[a].push_back(b);
v[b].push_back(a);
}
dfs(0, 1, 1);
for (int i = 1; i <= 16; i++) {
for (int j = 2; j <= n; j++) {
parent[j][i] = parent[parent[j][i - 1]][i - 1];
}
}
int m; cin >> m;
for (int i = 0; i < m; i++) {
int a, b;
cin >> a >> b;
cout << getA(a, b) << '\n';
}
}
'ps' 카테고리의 다른 글
[백준] 10217 - KCM Travel (0) | 2022.08.04 |
---|---|
[백준] 13334 - 철로 (0) | 2022.08.04 |
[백준] 3687 - 성냥개비 (0) | 2022.08.03 |
[백준] 1256 - 사전 (0) | 2022.08.03 |
[백준] 1562 - 계단수 (0) | 2022.08.03 |
댓글