fragment-header
fragment-markdown
홈
로그인
로그아웃
내 블로그
설정
로그인
백준 17073 (C++) 나무 위의 빗물
최초 업로드: 2025-04-05 06:44:23
최근 수정 시간: 2025-07-25 10:04:05
게시자: rlatjwls3333
카테고리: 백준
조회수: 11
# [Gold V] 나무 위의 빗물 #### [문제 링크](https://www.acmicpc.net/problem/17073) ## 문제 설명 <p style="text-align: center;"><img alt="" src="https://upload.acmicpc.net/96077f22-38dc-4cab-8122-1a693bc3928f/-/preview/" style="height: 282px; width: 300px;"><br> </p> <p>트리란, 사이클이 없는 연결 그래프를 의미한다. 위 그림은 1번 정점을 루트로 하는 어떤 트리를 나타낸 모습이다.</p> <p>사실 이 트리는 영훈이가 뒷마당에서 기르고 있는 나무이다. 어제는 비가 왔기 때문에, 트리의 1번 정점에는 <em>W</em>만큼의 물이 고여 있다. 1번 정점을 제외한 모든 정점에는 아직 물이 고여 있지 않은 상태이다.</p> <p>이제 매초마다 모든 정점은 아래의 작업을 순서대로 반복한다.</p> <ul> <li>물을 가지고 있으며, 자식 정점이 있다면 자식 정점 중 하나를 골라 물을 1 준다. 자식 정점이 여러 개라면 동일한 확률로 그 중 하나를 고른다.</li> <li>만약 부모 정점이 자신에게 물을 흘려보냈다면 받아서 쌓아 둔다.</li> </ul> <p>이때, 위 작업은 순서대로 진행되므로 부모 정점에게 받은 물을 즉시 자식 정점에게 줄 수는 없다.</p> <p>영훈이는 나무를 바라보면서 더 이상 물이 움직이지 않는 상태가 되었을 때 각 정점에 어느 정도의 물이 있게 될지 궁금해졌다. 더 이상 물이 움직이지 않을 때, <em>i</em>번 정점에 쌓인 물의 양의 기댓값을 <em>P<sub>i</sub></em>라 하자. 이때, <em>P<sub>i</sub></em>가 0보다 큰 정점들에 대해서 <em>P<sub>i</sub></em>들의 평균은 어느 정도가 될까?</p> ## 입력 <p>첫째 줄에 트리의 노드의 수 <em>N</em>과 1번 노드에 고인 물의 양을 의미하는 정수 <em>W</em>가 주어진다. (2 ≤ <em>N </em>≤ 500,000, 1 ≤ <em>W</em> ≤ 10<sup>9</sup>)</p> <p>다음 <em>N-1</em>줄에 걸쳐, 트리에 존재하는 간선의 정보가 <em>U V</em>의 형태로 주어진다. (1 ≤ <em>U</em>,<em> V</em> ≤<em> N</em>, <em>U </em>≠ <em>V</em>)</p> <p>이는 양 끝 정점이 각각 <em>U</em>와 <em>V</em>인 간선이 트리에 존재한다는 의미이다.</p> <p>입력으로 주어지는 트리는 항상 올바른 연결 트리임이 보장되며, 주어지는 트리의 루트는 항상 1번 정점이다.</p> ## 출력 <p>문제의 정답을 출력한다. 정답과의 차이가 10<sup>-3</sup> 이하인 값은 모두 정답으로 인정된다.</p> ## 풀이 #### 부모 노드에 있는 빗물은 자식이 있다면 물이 무조건 자식 노드로 내려갑니다. 모든 이동이 끝난 후에는 결국 모든 물은 최종 자식 노드인 리프 노드 위에만 위치하게 됩니다. 따라서 P<sub>i</sub>의 물의 평균은 전체 물의 양인 W를 리프 노드의 수로 나눈 값이 됩니다. 리프노드는 엣지가 1인 정점들의 개수를 구하면 쉽게 구할 수 있습니다. ``` c++ #include<bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(0); cin.tie(0); int N, W; cin >> N >> W; vector<vector<int>> conn(N+1); for(int i=0;i<N-1;i++) { int U, V; cin >> U >> V; conn[U].push_back(V); conn[V].push_back(U); } double leafCnt=0; for(int i=2;i<=N;i++) { if(conn[i].size()==1) leafCnt++; } cout << setprecision(4) << fixed << W/leafCnt; } ```