https://www.acmicpc.net/problem/17073
17073번: 나무 위의 빗물
첫째 줄에 트리의 노드의 수 N과 1번 노드에 고인 물의 양을 의미하는 정수 W가 주어진다. (2 ≤ N ≤ 500,000, 1 ≤ W ≤ 109) 다음 N-1줄에 걸쳐, 트리에 존재하는 간선의 정보가 U V의 형태로 주어진다
www.acmicpc.net
문제이해가 살짝 어려운 문제입니다.
이제 매초마다 모든 정점은 아래의 작업을 순서대로 반복한다.
- 물을 가지고 있으며, 자식 정점이 있다면 자식 정점 중 하나를 골라 물을 1 준다. 자식 정점이 여러 개라면 동일한 확률로 그 중 하나를 고른다.
- 만약 부모 정점이 자신에게 물을 흘려보냈다면 받아서 쌓아 둔다.
라고 써있어서 처음에 1씩 빼면서 연산하는 줄알았는데
. 더 이상 물이 움직이지 않을 때, i번 정점에 쌓인 물의 양의 기댓값을 Pi라 하자.
라고 써있어서 나중에 물이 움직이지 않는다는것은 결국 모든 물이 다 내려가야한다는 것을 의미한다고 깨닳았습니다.
결국 모든 물은 리프노드로 가게 되어 있으므로 리프 노드의 개수를 구하여
W / 리프노드의 개수 = 평균값. 이 나옵니다.
기억해야할점들
첫번째, 루트노드는 제외하고 간선이 1개인 점을 구해야만합니다.
코드입니다.
import java.util.ArrayList; import java.util.Scanner; public class Main { static ArrayList<ArrayList<Node>> tree = new ArrayList<ArrayList<Node>>(); static long[] water; static Node root = new Node(); public static void main(String[] args) { Scanner sc = new Scanner(System.in); int N= sc.nextInt(); int W = sc.nextInt(); water = new long[N]; water[1] = W; for(int i=0;i<=N;i++) { tree.add(new ArrayList<Node>()); } for(int i=0;i<N-1;i++) { int U = sc.nextInt(); int V = sc.nextInt(); tree.get(U).add(new Node(V)); tree.get(V).add(new Node(U)); } int leafNodeCnt = 0; for(int i=2; i<=N; i++) { if(tree.get(i).size() == 1) leafNodeCnt+=1; } System.out.println( (double)W/leafNodeCnt); } static class Node{ int index; Node(){ } Node(int index){ this.index = index; } } }
'알고리즘 > Tree' 카테고리의 다른 글
[백준] 가장 가까운 공통 조상 - 골드4, 트리(Tree) (0) | 2023.01.13 |
---|---|
[백준] 1967 트리의 지름 - 골드4, DFS + 트리(Tree) 자바 (0) | 2023.01.13 |
[백준] 트리 - 골드5, 트리(Tree) (0) | 2023.01.12 |
[백준] 단절점과 단절선 - 실버1, 트리(Tree) (0) | 2023.01.12 |
[백준] 1991 트리 순회 - 실버1, 트리(Tree) + DFS (0) | 2023.01.11 |