넘치게 채우기

[BOJ] 28360: 양동이 게임 본문

PS/BOJ

[BOJ] 28360: 양동이 게임

riveroverflow 2024. 9. 23. 16:58
728x90
반응형

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

BOJ - 양동이 게임

문제 유형 : 그리디, 그래프

문제 난이도 : Silver I

 

문제

찬우는 천하제일 코딩대회 참가자들과 간단한 게임을 하기로 했다. 게임은 '양동이 게임'으로, 맨 위의 양동이에 물을 만큼 부어 흘려보냈을 때 최종적으로 가장 많은 물이 담긴 양동이를 선택하면 이기는 게임이다. 양동이를 고르기 전까지는 연결 상태를 알 수 없다. 하지만 찬우는 양동이들이 어떻게 연결되어 있는지 이미 알고 있는 상태였다! 찬우가 게임을 이기기 위해서 골라야 하는 양동이에는 얼마만큼의 물이 들어있는지 알아보자.

 1번 양동이가 항상 맨 위에 있으며, 의 양만큼 물이 채워져 있는 양동이에 개의 나가는 방향 호스가 연결되어 있으면 양동이가 비워질 때까지 호스당  씩 흐른다. 또한 양동이의 번호가 더 작을수록 위에 있기 때문에, 물은 항상 번호가 작은 양동이에서 큰 양동이로 흐른다.

 

입력

첫째 줄에 양동이의 개수 N과 호스의 개수 이 공백으로 구분되어 주어진다. (1≤N≤50; 0≤M≤100)

둘째 줄부터 M개의 줄에 걸쳐 호스의 정보를 나타내는 두 정수 , 가 공백으로 구분되어 주어진다. (1≤v<w≤N) 이는 v번 양동이에서 w번 양동이로 물이 흐르는 호스가 있다는 뜻이다.

연결하는 양동이가 같은 호스가 여러 개 주어지지 않는다. 즉, 주어지는 모든쌍은 서로 다르다.

 

출력

 1번 양동이에 물을 100만큼 채워서 흘려보냈을 때, 한 양동이에 가장 많이 들어있는 물의 양을 출력한다. 실제 정답과 출력값의 절대오차 또는 상대오차가  이하이면 정답으로 처리한다.

 

풀이

양동이를 정점, 호스를 간선이라 치고, 방향 그래프를 만든다.

무조건 작은 번호의 양동이가 큰 양동이로 주는 구조기에, bfs / dfs 말고, 단순 반복문으로 해결할 수 있다.

처음에 1번에 100.0의 물을 할당하고, 1번부터 순차적으로 다음 양동이들에게 (자신의 물양) / (진출차수)만큼 준다.

 

물양 배열의 최대값을 반환한다.

 

코드

C++

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main (int argc, char *argv[]) {
  int n, m;
  cin >> n >> m;
  vector<vector<int>> graph(n+1);
  vector<float> water(n+1, 0.0);
  for(int i = 0; i < m; ++i) {
    int v, w;
    cin >> v >> w;
    graph[v].push_back(w);
  }

  water[1] = 100.0;

  for(int i = 1; i <= n; ++i) {
    int outdegree = graph[i].size();
    for(const auto &next : graph[i]) {
      water[next] += water[i] / outdegree;
    }
    if(outdegree > 0) water[i] = 0.0;
  }

  float maxWater = *max_element(water.begin(), water.end());
  cout << maxWater << "\n";
  return 0;
}
 
728x90
반응형

'PS > BOJ' 카테고리의 다른 글

[BOJ] 23631: 진심 좌우 반복뛰기  (0) 2024.09.25
[BOJ] 1080: 행렬  (0) 2024.09.24
[BOJ] 21558: 전쟁 준비하기  (0) 2024.09.22
[BOJ] 4531: Verdis Quo  (0) 2024.09.20
[BOJ] 11183: Coast Length  (0) 2024.09.19