본문 바로가기
ps

[백준] 11437 - LCA

by kariskan 2022. 8. 3.

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

댓글