티스토리 뷰
문제
3584번: 가장 가까운 공통 조상
루트가 있는 트리(rooted tree)가 주어지고, 그 트리 상의 두 정점이 주어질 때 그들의 가장 가까운 공통 조상(Nearest Common Anscestor)은 다음과 같이 정의됩니다. 두 노드의 가장 가까운 공통 조상은, 두
www.acmicpc.net
풀이
LCA(Lowest Common Ancestor)를 사용합니다.
사실 이번 문제는 전에 풀었던 11438 - LCA 2문제와 거의 다를 것이 없습니다.
다만, 다른 점이라면 루트노드가 따로 주어지지 않기 때문에 직접 찾아야한다는 것입니다.
하지만 그건 어렵지 않습니다.
먼저, 각 테스트케이스별 간선들의 정보를 입력받은 다음 노드 하나를 무작위로 골라서 더 이상 못 올라갈 때까지 올라갑니다.
더 이상 못 올라가는 상황이 될 때의 노드가 루트 노드가 됩니다.
루트 노드를 구하고 나면 LCA로 문제를 풀면 됩니다.
(참고: 백준 11438 - LCA 2 풀이)
코드
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> p;
const int MAX_LVL = 30;
int N, root;
vector<vector<int>> graph;
vector<vector<int>> par;
vector<int> depth;
void find_root(int cur) {
if (par[cur][0] == 0) {
root = cur;
return;
}
find_root(par[cur][0]);
}
void solve(int cur, int pnode) {
depth[cur] = depth[pnode] + 1;
par[cur][0] = pnode;
for (int i = 1; i <= MAX_LVL; ++i)
par[cur][i] = par[par[cur][i - 1]][i - 1];
for (int i = 0; i < graph[cur].size(); ++i) {
int next = graph[cur][i];
if (next != pnode)
solve(next, cur);
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) {
int pnt;
cin >> N;
graph.clear();
graph.resize(N + 1);
par.clear();
par.resize(N + 1, vector<int>(MAX_LVL + 1, 0));
depth.clear();
depth.resize(N + 1, 0);
for (int i = 0; i < N - 1; ++i) {
int a, b;
pnt = a;
cin >> a >> b;
graph[a].push_back(b);
par[b][0] = a;
}
find_root(pnt);
solve(root, 0);
int a, b;
cin >> a >> b;
if (depth[a] != depth[b]) {
if (depth[a] > depth[b])
swap(a, b);
for (int i = MAX_LVL; i >= 0; --i)
if (depth[a] <= depth[par[b][i]])
b = par[b][i];
}
int lca = a;
if (a != b) {
for (int i = MAX_LVL; i >= 0; --i) {
if (par[a][i] != par[b][i]) {
a = par[a][i];
b = par[b][i];
}
lca = par[a][i];
}
}
cout << lca << "\n";
}
return 0;
}
'BOJ' 카테고리의 다른 글
[BOJ 7812] 중앙트리 (0) | 2021.05.12 |
---|---|
[BOJ 1761] 정점들의 거리 (0) | 2021.05.12 |
[BOJ 1949] 우수 마을 (0) | 2021.05.05 |
[BOJ 15681] 트리와 쿼리 (0) | 2021.05.05 |
[BOJ 11438] LCA 2 (0) | 2021.05.04 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- knapsack
- Tree
- Sliding Window
- Combinatorics
- Dijkstra
- LCA
- Bit Masking
- Constructive
- BOJ
- Greedy
- Priority Queue
- sorting
- Union Find
- Tree DP
- Coordinate Compression
- DP
- PBA
- graph
- binary search
- 737-2
- DP Traceback
- hello
- Prefix Sum
- codeforces
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
글 보관함