본문 바로가기

CodingTEST

[백준 17073] 나무 위의 빗물 (JAVA)

반응형

백준 17073번 문제 - 나무 위의 빗물

 

17073번: 나무 위의 빗물

첫째 줄에 트리의 노드의 수 N과 1번 노드에 고인 물의 양을 의미하는 정수 W가 주어진다. (2 ≤ N ≤ 500,000, 1 ≤ W ≤ 109) 다음 N-1줄에 걸쳐, 트리에 존재하는 간선의 정보가 U V의 형태로 주어진다

www.acmicpc.net


문제 분석

 

 

  • 더 이상 물이 움직이지 않을 때 : 마지막 리프로 모든 물이 다 내려갔을 때
  • 이 때 물이 존재하는 리프들이 물들의 평균을 구해 출력해라

 

해결 키 포인트
  • 마지막 리프 개수 구하는 법
    • 처음에는 BFS와 같이 큐를 제작하고 visited를 체크하면서 관련된 간선이 모두 visited된 상태일 경우 마지막 리프로 처리하는 방법 시도 → 실패 (이렇게 하면 문제가 생기는 듯)
    • 관련된 간선이 1개만 있을 경우, 부모와만 연결되어 있는 것이므로 마지막 리프로 처리하는 방법 → 이 방법으로 채택
  • 수가 커지면 지수 표기법으로 표기되는 문제 발생
    • 문제에서 '10^(-3)의 오차는 정답으로 처리한다.' 되어있으므로 소수점 4자리까지만 표시
  • 1번 노드는 최상위 루트니까 1번 노드는 확인하지 않는다.

코드
import java.io.*;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 노드 수(N)와 고인 물의 양(W) 입력
        StringTokenizer st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        double W = Double.parseDouble(st.nextToken());

        // 간선 정보 변수
        ArrayList<Integer>[] lists = new ArrayList[N + 1];
        for (int i = 1; i <= N; i++) {
            lists[i] = new ArrayList<>();
        }

        // N-1 개의 간선 정보 입력
        for (int i = 0; i < N - 1; i++) {
            st = new StringTokenizer(br.readLine());
            int u = Integer.parseInt(st.nextToken());
            int v = Integer.parseInt(st.nextToken());

            lists[u].add(v);
            lists[v].add(u);
        }

        // 최하단 리프 개수
        double count = 0;

        for (int i = 2; i <= N; i++) {
            if(lists[i].size() == 1)
                count++;
        }

        // 물이 멈췄을 경우는 모든 물이 최하단 리프에만 있음을 의미
        // 즉, (고인 물의 양 / 최하단 리프 개수) 출력
        System.out.println(String.format("%.10f", W/count));

    }
}
반응형