그래프 탐색 문제. 그 중에서도 트리 & DFS문제이다.
트리의 기본 개념만 안다면 쉽게 풀 수 있다.
조건을 하나 잘못 생각해서 틀렸었다.
문제풀이
어려운 것 없이,
부모 - 자식, 자식 - 부모 관계를 모두 저장해둔다. 그리고 각각 다음에 사용한다.
- 부모 - 자식 관계 : 트리에서 깊이 우선 탐색을 통해 리프 노드가 몇 개인지 구할 때 사용한다.
- 자식 - 부모 관계 : 지울 노드의 부모 노드의 번호를 구하고 해당 부모 노드에서 부모 - 자식 관계에서 지울 노드를 찾은 후 지울 때 사용한다.
루트 노드가 예시 케이스에서는 -1이 모두 첫번째로 나오긴 했지만,
나중에 나오는 경우를 대비해서도 코드를 구현했다.
/*
* 백준 1068번 트리
* https://www.acmicpc.net/problem/1068
* 그래프 탐색 - 깊이 우선 탐색 / 트리
*/
#include <iostream>
#include <vector>
using namespace std;
int rootNodeNum;
int nodeCnt;
int deleteNodeNum;
vector<int> childNode[50];
int parNode[50];
int ans;
void order(int nodeNum) {
//틀린 이유 : 그냥 지울 노드에 도착했을 경우 return하도록 했었음.
if (childNode[nodeNum].size() == 0) {
ans++;
return;
}
else {
for (int child : childNode[nodeNum]) {
order(child);
}
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> nodeCnt;
int parNodeNum;
for (int i = 0; i < nodeCnt; i++) {
cin >> parNodeNum;
if (parNodeNum == -1) {
rootNodeNum = i;
continue;
}
childNode[parNodeNum].push_back(i);
parNode[i] = parNodeNum;
}
cin >> deleteNodeNum;
if (deleteNodeNum != rootNodeNum) {
//해결책 - 지울 노드의 부모 노드의 자식 중에서 해당 지울 노드를 지운다.
int deleteNodeParent = parNode[deleteNodeNum];
for (int i = 0; i < childNode[deleteNodeParent].size(); i++) {
if (deleteNodeNum == childNode[deleteNodeParent][i]) {
childNode[deleteNodeParent].erase(childNode[deleteNodeParent].begin() + i);
break;
}
}
order(rootNodeNum);
}
cout << ans;
return 0;
}
코드에 주석으로도 달아놨지만, 처음에 내 풀이는
노드를 지워주지 않고 그냥 지울 노드에 도착했을 경우 바로 return하는 식으로 만들었다.
그러나 이렇게 할 경우
1-2-3-4 가 연결되고 4를 지웠을 때 리프 노드가 3이 되어야 하는데 3은 자식인 4를 가지고 있다고
판단하므로 리프노드가 되지 않는다.
따라서 그냥 모든 정보를 저장해 뒀다가 지울 노드의 정보를 지워주고 DFS 탐색을 했다.
코드는 위에서 확인 가능하다.
'알고리즘 > Baekjoon' 카테고리의 다른 글
[C++] 백준 13549번 숨바꼭질3 (2) | 2021.10.18 |
---|---|
[C++] 백준 12851번 숨바꼭질 2 (0) | 2021.10.18 |
[C++] 백준 1965번 상자넣기 (0) | 2021.10.13 |
[C++] 백준 1890번 점프 (5) | 2021.10.12 |
[C++] 백준 5014번 스타트링크 (0) | 2021.10.11 |