[문제보기]
3584. 가장 가까운 공통 조상
3584번: 가장 가까운 공통 조상
루트가 있는 트리(rooted tree)가 주어지고, 그 트리 상의 두 정점이 주어질 때 그들의 가장 가까운 공통 조상(Nearest Common Anscestor)은 다음과 같이 정의됩니다. 두 노드의 가장 가까운 공통 조상은, 두
www.acmicpc.net
[풀이과정]
이 문제는 LCA 알고리즘 이용 문제이다.
이 블로그를 참고하여 LCA 알고리즘을 보고 문제를 풀었다.
https://www.crocus.co.kr/660
[소스코드]
#include <iostream>
#include <vector>
#include <cstring>
#include <cmath>
using namespace std;
int n;
const int MAX = 100001;
vector<vector<int>> v;
int ac[MAX][20];
int depth[MAX];
int parent[MAX];
int max_level;
void Make_Tree(int cur, int parent){
depth[cur] = depth[parent] +1;
ac[cur][0] = parent;
for(int i=1; i<max_level; i++){
int temp = ac[cur][i-1];
ac[cur][i] = ac[temp][i-1];
}
max_level = (int)floor(log2(MAX));
for(int i=0; i<v[cur].size(); i++){
if(v[cur][i] != parent){
Make_Tree(v[cur][i], cur);
}
}
}
int main(){
int T;
cin >> T;
while(T--){
memset(depth, 0, sizeof(depth));
memset(ac, 0, sizeof(ac));
memset(parent, 0, sizeof(parent));
for(int i=0; i<MAX; i++)
v[i].clear();
cin >> n;
for(int i=0; i<n-1; i++){
int a, b; cin >> a >> b;
v[b].push_back(a);
v[a].push_back(b);
parent[b] = a;
}
int root;
for(int i=1; i<=n; i++){
if(parent[i] == 0){
root = i;
break;
}
}
depth[0] = -1;
Make_Tree(root, 0);
int x, y;
cin >> x >> y;
if(depth[x] != depth[y]){
if(depth[x] > depth[y])
swap(x, y);
for(int i = max_level-1; i>=0; i--){
if(depth[x] <= depth[ac[y][i]])
y = ac[y][i];
}
}
int lca = x;
if(x != y){
for(int i= max_level-1; i>=0; i--){
if(ac[x][i] != ac[y][i]){
x = ac[x][i];
y = ac[y][i];
}
lca = ac[x][i];
}
}
cout << lca << "\n";
}
}
[해결과정 중 실수한 부분]
'알고리즘 스터디 > Beakjoon' 카테고리의 다른 글
| [백준 15681][C++] 트리와 쿼리 (Gold 5) (0) | 2020.10.06 |
|---|---|
| [백준 1012][C++] 유기농 배추 (Silver 2) (0) | 2020.10.06 |
| [백준 4803][C++] 트리 (Gold 4) (0) | 2020.10.06 |
| [백준 14675][C++] 단절점과 단절선 (Gold 5) (0) | 2020.10.06 |
| [백준 4256][C++] 트리 (Gold 5) (0) | 2020.10.01 |