Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- docker-compose
- Java
- 메모이제이션
- 트리
- 구간 트리
- spring boot
- 달팽이
- 이분 매칭
- 스택
- 스프링 시큐리티
- Spring Cloud Config
- 이분 탐색
- Zuul
- 게이트웨이
- 서비스 디스커버리
- 다익스트라
- 플로이드 와샬
- 구현
- 주울
- dp
- 완전 탐색
- BFS
- 백트래킹
- ZuulFilter
- Gradle
- spring cloud
- 도커
- Logback
- 유레카
- 비트마스킹
Archives
- Today
- Total
Hello, Freakin world!
[백준 1068번][Java] 트리 - 리프노드 세기, 노드 지우기 본문
단순히 DFS 한 번에 풀 수 있는 문제인 줄 알았지만, 처리해야될 예외 사항이 좀 있습니다.
각 서브트리 루트에 리프노드의 개수를 저장하는 알고리즘이 있다고 합시다.
그 알고리즘을 이용해 위와 같은 결과를 만들어 냈습니다. 여기서 2번 노드를 지우려면 루트 노드의 값(3)에서 2번 노드의 값(1)을 빼면 답이 됩니다.
하지만... 다음의 경우는 어떨까요?
위에서 1번 노드를 제거하면 값이 0이 되어버립니다. 이처럼 해당 노드를 제거하면 루트 자신이 리프노드가 되는 경우 문제가 생깁니다. 위 예외들을 신경쓰지 않는 확실한 방법은 먼저 해당 노드를 트리에서 제외시키고 리프노드를 세는 겁니다.
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
/*
트리
https://www.acmicpc.net/problem/1068
*/
public class Main {
static int n, removeNode;
static Node[] nodes;
public static void main(String[] args) throws IOException {
// InputReader reader = new InputReader("testcase.txt");
InputReader reader = new InputReader();
n = reader.readInt();
nodes = new Node[n];
for (int i = 0; i < n; i++) {
nodes[i] = new Node(i);
}
int rootIdx = -1;
StringTokenizer st = new StringTokenizer(reader.readLine());
for (int i = 0; i < n; i++) {
int parent = Integer.parseInt(st.nextToken());
if(parent == -1) {
rootIdx = i;
continue;
}
nodes[parent].children.add(i);
}
removeNode = reader.readInt();
if(removeNode == rootIdx) {
System.out.println(0); return;
}
remove(rootIdx);
System.out.println(countLeaf(rootIdx));
}
private static void remove(int index) {
Node here = nodes[index];
for (int i = 0; i < here.children.size(); i++) {
int child = here.children.get(i);
if(child == removeNode) {
here.children.remove(i); return;
}
remove(child);
}
}
private static int countLeaf(int index) {
Node here = nodes[index];
if(here.children.size() == 0) return 1;
int cnt = 0;
for (int i = 0; i < here.children.size(); i++) {
int child = here.children.get(i);
cnt += countLeaf(child);
}
return cnt;
}
}
class Node {
int id;
List<Integer> children = new ArrayList<>();
public Node(int id) {
this.id = id;
}
}
class InputReader {
private BufferedReader br;
public InputReader() {
br = new BufferedReader(new InputStreamReader(System.in));
}
public InputReader(String filepath) {
try {
br = new BufferedReader(new FileReader(filepath));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public List<Character> readLineIntoCharList() throws IOException {
List<Character> l = new ArrayList<>();
while(true) {
int readVal = br.read();
if(readVal == '\n' || readVal == -1) break;
l.add((char)readVal);
}
return l;
}
public boolean ready() throws IOException {
return br.ready();
}
public String readLine() throws IOException {
return br.readLine();
}
public int readInt() throws IOException {
return Integer.parseInt(readLine());
}
public Long readLong() throws IOException {
return Long.parseLong(readLine());
}
}
'알고리즘 > PS' 카테고리의 다른 글
[백준 9372번][Java] 상근이의 여행 - 그래프 순회 (0) | 2020.10.09 |
---|---|
[백준 12865번][Java] 평범한 배낭 - 점화식과 구현의 관계 (0) | 2020.10.09 |
[백준 1967번][Java] 트리의 지름 - 재귀 호출 전/후 함수 호출 (0) | 2020.10.09 |
[백준 1208번][Java] 부분수열의 합 2 - 중간에서 만나기? (0) | 2020.10.09 |
[백준 1389번][Java] 케빈 베이컨의 6단계 법칙 - 플로이드 와샬 (0) | 2020.10.07 |
Comments