[백준] 3584_가장 가까운 공통 조상 C++


LCA, 최소 공통 조상을 찾는 문제

정답제출코드


#include <iostream>

#define MAX 10001

using namespace std;

int N;
int Parent[MAX];
bool visited[MAX];

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int T;
    cin >> T;

    for (int tc = 0; tc < T; ++tc)
    {
        cin >> N;

        for (int i = 1; i <= N; ++i)
        {
            Parent[i] = i;
            visited[i] = false;
        }
        
        for (int i = 0; i < N - 1; ++i)
        {
            int a, b;
            cin >> a >> b;
            Parent[b] = a;
        }

        int u, v;
        cin >> u >> v;
        visited[u] = true;

		while (u != Parent[u])
		{
			u = Parent[u];
			visited[u] = true;
		}
		while (true)
		{
			if (visited[v])
			{
				cout << v << '\n';
				break;
			}
			v = Parent[v];
		}
    }

    return 0;
}

LCA의 기초 문제이다.

이전에 풀었던 방법이 생각이 난다.

부모 노드를 거슬러 올라가면서 DFS를 진행하면서 찾는 다른 노드가 있는지 탐색을 했는데

DFS를 돌리는 수가 늘어나면 결국에 시간복잡도는 정말 최악의 경우 O(N^3)이 되기에

노드가 10000개인 편향트리를 탐색하게 된다면 이건 정말로 타임오버감이다.

그래서 나온 방법이 위의 방법으로,

한쪽에서 부모 노드를 거슬러 올라가면서 방문처리를 해주고

다른쪽에서 부모 노드를 거슬러 올라가면서 방문 처리한 노드를 만나면

그 노드가 바로 교차점, 즉 최소 공통 조상인 것이다.

이렇게 하면 O(2N)으로 줄일 수 있다.


© 2022.07. by Wookey_Kim

Powered by Hydejack v7.5.2