백준 15681 트리와 쿼리 - JAVA

2025. 3. 17. 18:30·알고리즘/백준

15681 문제 링크


https://www.acmicpc.net/problem/15681

 

문제 설명


 

입출력


 

코드


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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import java.io.*;
import java.util.*;
 
public class Main {
    private static List<List<Integer>> list = new ArrayList<>();
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        
        StringTokenizer st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        int R = Integer.parseInt(st.nextToken());
        int Q = Integer.parseInt(st.nextToken());
        StringBuilder sb = new StringBuilder();
        int[] qArray = new int[Q];
        boolean[] visit = new boolean[N+1];
        int[] children = new int[N+1];
        
        for (int i = 0; i <= N; i++) {
            list.add(new ArrayList<>());
        } 
        for (int i = 0; i < N - 1; i++) {
            st = new StringTokenizer(br.readLine());
            int start = Integer.parseInt(st.nextToken());
            int end = Integer.parseInt(st.nextToken());
            list.get(start).add(end);
            list.get(end).add(start);
        } 
        for (int i = 0; i < Q; i++) {
            qArray[i] = Integer.parseInt(br.readLine());
        } 
        dfs(R, visit, children);
        for (int i = 0; i < qArray.length; i++) {
            sb.append(children[qArray[i]]).append("\n");
        } 
        bw.write(sb.toString());
        bw.flush();
    }
    
    private static void dfs(int r, boolean[] visit, int[] children) {
        visit[r] = true;
        children[r]++;
        for (int i = 0; i < list.get(r).size(); i++) {
            int current = list.get(r).get(i);
            if (!visit[current]) {
                dfs(current, visit, children);
                children[r] += children[current];
            }
        } 
    }
}
Colored by Color Scripter
cs

 

알고리즘 설명


이 문제는 자식 노드를 가진 부모 노드가 그 자식 노드를 몇 개 가지고 있는지 묻는 문제입니다. DFS 알고리즘을 사용하여 각 노드별로 자식 노드를 찾는 것은 다른 문제들과 유사하지만, 해당 문제는 각 노드가 가진 자식 수를 계산하는 방법에 대해 고민해야 합니다. 재귀적으로 접근하면, 부모 노드는 그 자식들의 자식 수를 재귀적으로 확인하여 각 자식의 자식 수를 부모에게 더하는 방식으로 해결할 수 있습니다. DFS 문제에 어느 정도 익숙해지셨다면 어렵지 않게 풀 수 있는 문제였다고 생각합니다.”

 

코드 해석


트리의 정점 수 N, 루트 노드 R, 쿼리 수 Q를 입력받습니다. 문제에서 주어진 노드들의 연결은 트리 구조를 이루고 있으며, 트리의 간선 수는 정점 수에서 1을 뺀 값이므로, 총 N-1개의 간선 정보를 입력받습니다. 그런 다음, 쿼리에서 요구하는 노드들에 대해 그 노드를 루트로 하는 서브트리의 자식 노드 수를 구해야 합니다.

 

DFS 탐색을 통해 트리 구조를 순회하면서 각 노드가 가진 자식 노드들의 개수를 계산합니다. 트리 순회를 시작할 때, 루트 노드인 r도 노드의 개수에 포함해야하기 때문에 children[r]++로 루트 노드를 더해줍니다. 각 노드들의 자식 노드의 개수만을 세기위해 방문 여부를 체크하는 visit 배열을 사용하여 이미 방문한 노드는 다시 방문하지 않도록 처리합니다. 이렇게 하면 부모 노드가 이미 방문한 노드를 다시 세지 않도록 할 수 있습니다. 각 노드에 대해서는 자식 노드들의 자식 수를 누적하여 부모 노드의 자식 노드 개수에 반영됩니다. 탐색이 완료되면, children배열에서 쿼리에서 요구하는 노드를 루트노드로 하는 서브트리에 속한 정점의 수를 출력합니다.

 

'알고리즘 > 백준' 카테고리의 다른 글

백준 2143 두 배열의 합 - JAVA  (0) 2025.03.25
백준 2239 스도쿠 - JAVA  (0) 2025.03.24
백준 1197 최소 스패닝 트리 - JAVA  (0) 2025.03.06
백준 9465 스티커 - JAVA  (0) 2025.03.03
백준 14502 연구소 - JAVA  (0) 2025.03.03
'알고리즘/백준' 카테고리의 다른 글
  • 백준 2143 두 배열의 합 - JAVA
  • 백준 2239 스도쿠 - JAVA
  • 백준 1197 최소 스패닝 트리 - JAVA
  • 백준 9465 스티커 - JAVA
BIS's tech Blog
BIS's tech Blog
Welcome to Kanghyun's tech blog :)
  • BIS's tech Blog
    벼익숙의 기술 블로그
    BIS's tech Blog
  • 전체
    오늘
    어제
    • 분류 전체보기 (63)
      • 알고리즘 (49)
        • 백준 (40)
        • 프로그래머스 (9)
      • CS 스터디 (14)
        • CS - JAVA (11)
        • CS - DB (3)
      • 프로젝트 (0)
      • Spring (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    재귀
    동적 계획
    깊이 우선 탐색
    백준
    기술질문
    BFS
    알고리즘 고득점 kit
    너비 우선 탐색
    bottom-up
    Lv2
    Top-Down
    CS
    Baekjoon
    java
    DFS
    브루트포스
    dp
    자료구조
    프로그래머스
    완전탐색
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
BIS's tech Blog
백준 15681 트리와 쿼리 - JAVA
상단으로

티스토리툴바