길민호(ethan.mino)
코딩수첩
길민호(ethan.mino)
전체 방문자
오늘
어제
  • 분류 전체보기 (215)
    • Computer Science (0)
    • Web (6)
      • CSS (0)
      • HTML (0)
    • Node.js (0)
    • Javascript (2)
    • Java (46)
      • Spring (27)
      • Jsp (0)
    • C\C++ (2)
    • Programming (0)
    • AI (0)
    • Database (7)
    • Git (5)
    • Algorithm (119)
      • Stack (0)
      • Queue (0)
      • Linked List (0)
      • Sort (0)
      • Simulation (27)
      • Recursion (0)
      • Backtracking (4)
      • Two Pointer (3)
      • Dynamic Programming (19)
      • Greedy (10)
      • Graph (3)
      • Dijkstra (1)
      • BFS\DFS (8)
      • Floyd (1)
      • MST (4)
      • Tree (4)
      • Binary Search (8)
      • Binary Search Tree (4)
    • IntelliJ (4)
    • Vscode (0)
    • Operating System (0)
    • 후기 (3)
    • 성장일지 (13)
    • 스터디 (7)
    • 설치 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • ㅡ

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
길민호(ethan.mino)

코딩수첩

Algorithm/Tree

[SW Expert Academy 1248번] 공통 조상

2022. 7. 3. 02:32

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV15PTkqAPYCFAYD 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com


 

공통 조상 문제는 크기 두 개의 과정이 필요합니다.

  1. 공통 조상 찾기
  2. 서브 트리 크기 계산

공통 조상 찾기는 아래의 과정으로 구할 수 있습니다.

  1. a 정점의 모든 부모 노드를 구한다.
  2. b 정점의 모든 부모 노드를 구한다.
  3. 이분 탐색을 위해 b 정점의 모든 노드를 정렬한다.
  4. a에 가까운 조상부터 b 정점의 조상 노드에 포함되어 있는지 확인한다.

서브 트리 크기 구하기는 아래의 과정으로 구할 수 있습니다.

  1. 왼쪽 자식 서브 트리의 크기를 구한다.
  2. 오른쪽 자식 서브 트리의 크기를 구한다.
  3. 자식 서브 트리의 크기에 1을 더해준다.

 

아래는 전체 코드입니다.

// Created by 길민호 on 2022/07/02.

#include <bits/stdc++.h>
using namespace std;

#define SIZE 10001
int p[SIZE];

vector<int> Ancestor(int v){  // 정점의 모든 조상을 벡터에 담아 반환하는 함수
    vector<int> anc;    //
    int cur = v;    // v부터 시작
    while(cur != 1){
        anc.push_back(p[cur]);  // 부모 노드를 담음
        cur = p[cur];   // cur은 부모로 이동
    }
    return anc; // 조상 노드 반환
}

int tree_size(int root, vector<vector<int>>& c){   // root의 서브 트리의 크기를 구하는 함수
    if(c[root].size() == 0) return 1;  // leaf 노드인 경우

    // 자식 노드의 서브 트리 크기를 계산해서 더해줌
    int size = 0;
    for(auto v : c[root]) size += tree_size(v, c);
    return size + 1;
}

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

    int t; cin >> t;
    int th = 1;
    while(t--){
        int v, e, a, b; cin >> v >> e >> a >> b;
        vector<vector<int>> c(v + 1);  // 자식 노드 번호를 저장하는 리스트

        for(int i = 0; i < e; i++){
            int parent, child; cin >> parent >> child;
            p[child] = parent;  // 각 정점의 부모 노드를 저장
            c[parent].push_back(child);    // 자식 노드 번호를 저장
        }

        vector<int> p_a = Ancestor(a);
        vector<int> p_b = Ancestor(b);

        sort(p_b.begin(), p_b.end());   // 이진 탐색을 위해 b 정점의 조상을 정렬

        int root = 0;   // 공통 조상의 번호
        for(int idx = 0; idx < p_a.size(); idx++){
             bool find = binary_search(p_b.begin(), p_b.end(), p_a[idx]);   // a 정점의 조상을 b 정점의 조상에서 찾음
             if(find) { // 찾은 경우
                 root = p_a[idx];
                 break;
             }
        }
        int size = tree_size(root, c);  // 공통 조상의 서브 트리 크기를 구함
        cout << "#" << th++ << " " << root << " " << size << "\n";
    }
}

 

'Algorithm > Tree' 카테고리의 다른 글

[백준 20955번] 민서의 응급 수술 (C++)  (0) 2022.06.05
[백준 15681] 트리와 쿼리 (C++)  (0) 2022.06.04
[백준 4803번] 트리 (C++)  (0) 2022.06.04
    'Algorithm/Tree' 카테고리의 다른 글
    • [백준 20955번] 민서의 응급 수술 (C++)
    • [백준 15681] 트리와 쿼리 (C++)
    • [백준 4803번] 트리 (C++)
    길민호(ethan.mino)
    길민호(ethan.mino)
    💻 호기심 많은 서버 개발자 길민호입니다.

    티스토리툴바