https://www.acmicpc.net/problem/5847
5847번: Milk Scheduling
Farmer John's N cows (1 <= N <= 10,000) are conveniently numbered 1..N. Each cow i takes T(i) units of time to milk. Unfortunately, some cows must be milked before others, owing to the layout of FJ's barn. If cow A must be milked before cow B, then FJ need
www.acmicpc.net
유향 그래프를 DFS로 탐색하는 문제이다.
직원이 모든 소의 우유를 동시에 짤 수 있을 정도로 많으므로, 각 소의 우유를 짜는 데에 걸리는 시간 중 최댓값이 곧 문제의 정답이다. 이 때 먼저 우유를 짜야 하는 소가 있는 경우, 해당 소의 우유를 짜는 시간에 먼저 우유를 짜야 하는 소의 우유 짜는 시간의 최댓값을 더하면 되므로 DFS와 메모이제이션을 이용해 빠른 시간 안에 풀 수 있다.
#include <cstdio>
#include <vector>
using namespace std;
#define MAX_N 10000
// visit[i]: dfs에서 노드 i를 방문했다면 true, 아니라면 false
bool visit[MAX_N];
// T[i]: i번째 소의 우유를 짜는 데에 걸리는 시간
int T[MAX_N];
// rule[i]: i번째 소의 우유를 짜기 전에 우유를 짜야 할 소의 집합
vector<int> rule[MAX_N];
int max(int a, int b) { return a > b ? a : b; }
// node번째 소의 우유를 짜는 시간을 계산
int dfs(int node) {
// 현재 소보다 보다 먼저 우유를 짜야 할 소들의 우유를 짜는 데에 걸리는 총 시간
int before = 0;
// 현재 소의 우유 짜는 시간을 아직 계산하지 않았다면
if (!visit[node]) {
// 현재 소보다 보다 먼저 우유를 짜야 하는 소들의 우유 짜는 시간을 계산해
// 그 최댓값을 before에 저장
for (auto n : rule[node]) before = max(before, dfs(n));
// 현재 소의 우유 짜는 시간을 계산했음을 표시
visit[node] = true;
}
// 현재 소의 우유를 짜는 시간과
// 먼저 우유를 짜야 할 소들의 우유짜는 총 시간을 더한 값을 반환
return T[node] += before;
}
int main() {
// N: 소의 마리 수, M: 제약의 수, A, B: 제약 A -> B
// ans: 모든 소의 우유를 짜는 데에 걸리는 총 시간
int N, M, A, B, ans = 0;
// 문제의 조건을 입력받은 뒤
scanf("%d %d", &N, &M);
for (int i = 0; i < N; i++) scanf("%u", T + i);
while (M--) {
scanf("%d %d", &A, &B);
rule[--B].push_back(--A);
}
// 각 소의 우유짜는 시간을 계산해 그 최댓값을 출력
for (int i = 0; i < N; i++) ans = max(ans, dfs(i));
printf("%u\n", ans);
return 0;
}
'알고리즘 > 문제 풀이' 카테고리의 다른 글
백준 1976번: 여행가자 (0) | 2022.07.01 |
---|---|
백준 2317번: 결혼식 (0) | 2022.07.01 |
백준 23358번: Quack Strikes Back (Easy) (0) | 2022.06.30 |
백준 16118번: 달빛 여우 (0) | 2022.06.30 |
백준 14658번: 하늘에서 별똥별이 빗발친다 (0) | 2022.06.16 |