[C++] 백준 1068번 트리

lacram·2021년 8월 3일
0

백준

목록 보기
43/60

문제

트리에서 리프 노드란, 자식의 개수가 0인 노드를 말한다.

트리가 주어졌을 때, 노드 하나를 지울 것이다. 그 때, 남은 트리에서 리프 노드의 개수를 구하는 프로그램을 작성하시오. 노드를 지우면 그 노드와 노드의 모든 자손이 트리에서 제거된다.

입력

첫째 줄에 트리의 노드의 개수 N이 주어진다. N은 50보다 작거나 같은 자연수이다. 둘째 줄에는 0번 노드부터 N-1번 노드까지, 각 노드의 부모가 주어진다. 만약 부모가 없다면 (루트) -1이 주어진다. 셋째 줄에는 지울 노드의 번호가 주어진다.

출력

첫째 줄에 입력으로 주어진 트리에서 입력으로 주어진 노드를 지웠을 때, 리프 노드의 개수를 출력한다.

풀이

간단해보이는 문제지만 함정이 많아 정답률이 낮다.
트리를 탐색하며 리프노드에 도착할 경우 정답에 1을 추가한다. 제거되는 노드에는 방문하지않는다.
트리가 일렬로 주어질 경우와 루트가 지워질 경우를 고려해 문제를 풀어야한다.

#include <iostream>
#include <vector>
#include <cstring>
#include <fstream>
#include <algorithm>
#include <cmath>
#define endl '\n'

using namespace std;

int n;
int node;
vector<int> child[50];

int solve(int root){

  if (child[root].empty()) return 1;

  int ret = 0;

  for (int i=0; i<child[root].size(); i++){
    if (child[root][i] == node) {
      if (child[root].size() == 1) ret++;
      continue;
    }
    ret += solve(child[root][i]);
  }

  return ret;
}

int main(){
  ios_base :: sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);

  // ifstream cin;
  // cin.open("input.txt");

  cin >> n;
  int root;

  for (int i=0; i<n; i++){
    int parent;
    cin >> parent;
    
    if (parent == -1) {
      root = i;
      continue;
    }

    child[parent].push_back(i);
  }
  cin >> node;

  if (root == node) cout << 0;
  else cout << solve(root);
}
profile
기록용

0개의 댓글