[Gold / 1033] 칵테일
🔷 분류
수학, 그래프 이론, 그래프 탐색, 정수론, 유클리드 호제법
✒️ 문제 설명
august14는 세상에서 가장 맛있는 칵테일이다. 이 칵테일을 만드는 정확한 방법은 아직 세상에 공개되지 않았지만, 들어가는 재료 N개는 공개되어 있다.
경근이는 인터넷 검색을 통해서 재료 쌍 N-1개의 비율을 알아냈고, 이 비율을 이용해서 칵테일에 들어가는 전체 재료의 비율을 알아낼 수 있다.
총 재료 쌍 N-1개의 비율이 입력으로 주어진다. 이때, 칵테일을 만드는데 필요한 각 재료의 양을 구하는 프로그램을 작성하시오. 이때, 필요한 재료의 질량을 모두 더한 값이 최소가 되어야 한다. 칵테일을 만드는 재료의 양은 정수이고, 총 질량은 0보다 커야한다.
비율은 “a b p q”와 같은 형식이고, a번 재료의 질량을 b번 재료의 질량으로 나눈 값이 p/q라는 뜻이다.
⬅️ 입력
첫째 줄에 august14를 만드는데 필요한 재료의 개수 N이 주어지며, N은 10보다 작거나 같은 자연수이다.
둘째 줄부터 N-1개의 줄에는 재료 쌍의 비율이 한 줄에 하나씩 주어지는데, 문제 설명에 나온 형식인 “a b p q”로 주어진다. 재료는 0번부터 N-1까지이며, a와 b는 모두 N-1보다 작거나 같은 음이 아닌 정수이다. p와 q는 9보다 작거나 같은 자연수이다.
➡️ 출력
첫째 줄에 칵테일을 만드는데 필요한 각 재료의 질량을 0번 재료부터 순서대로 공백으로 구분해 출력한다.
💻 코드 (C++)
#include <iostream>
#include <vector>
#include <tuple>
using namespace std;
vector<tuple<int, int, int>> A[10]; // 재료 간 연결 리스트
long lcm; // 최소공배수
bool visited[10];
long D[10]; // 노드 값
long gcd(long a, long b) {
if(b == 0) return a;
else return gcd(b, a % b);
}
void DFS(int a) {
visited[a] = true;
for(auto i : A[a]) {
int next = get<0>(i);
if(!visited[next]) {
D[next] = D[a] * get<2>(i) / get<1>(i);
DFS(next);
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int n;
cin >> n;
lcm = 1;
for(int i = 0; i < n-1; i++) {
int a, b, p, q;
cin >> a >> b >> p >> q;
A[a].push_back(make_tuple(b, p, q));
A[b].push_back(make_tuple(a, q, p));
lcm *= (p * q) / gcd(p, q);
}
D[0] = lcm;
DFS(0);
long g = D[0]; // 최대공약수 구하기
for(int i = 1; i < n; i++) {
g = gcd(g, D[i]);
}
for(int i = 0; i < n; i++) {
cout << D[i] / g << " "; // 구한 값 최대 공약수로 나누기
}
return 0;
}
공유하기
Twitter Facebook LinkedIn글 이동
Comments