Problem Solving/BOJ

[백준 / BOJ] C++ 1005 ACM Craft

nageune 2023. 4. 6. 14:05
728x90
반응형

1005번: ACM Craft

 

문제

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

 

1005번: ACM Craft

첫째 줄에는 테스트케이스의 개수 T가 주어진다. 각 테스트 케이스는 다음과 같이 주어진다. 첫째 줄에 건물의 개수 N과 건물간의 건설순서 규칙의 총 개수 K이 주어진다. (건물의 번호는 1번부

www.acmicpc.net

 

 

풀이

1516번 문제와 비슷한 문제로 각 건물을 짓는 데는 먼저 지어져야 하는 건물이 있으므로 위상 정렬을 해야 한다. 특정 건물이 완성되기까지 걸리는 시간은 이전 건물이 완성되기까지 걸리는 최대 시간 + 특정 건물을 짓는 시간이다. 그리고 이전 건물에 대해서도 같은 과정을 반복하게 된다. 따라서 DP 테이블을 만들어 (누적 값 + 현재 추가 값)이 최대가 되도록 갱신해 주면 된다.

 

위상 정렬의 순서에 따라 다음에 지을 건물의 완성 시간을 현재 건물이 완성되기까지 누적 시간 + 다음 건물을 완성하는 데 걸리는 시간의 최댓값으로 갱신해 준다. 모든 건물에 대해 완성까지 걸리는 최소 시간을 구해준 다음, 특정 건물을 입력받고 그 건물에 대한 값만 출력해 주면 된다.

 

코드

#include <bits/stdc++.h>
using namespace std;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  int T;
  cin >> T;
  while (T--) {
    int N, K, W;
    vector<int> edge[1001], inDegree(1001, 0), cost(1001), ans;
    cin >> N >> K;
    for (int i = 1; i <= N; i++)
      cin >> cost[i];
    while (K--) {
      int u, v;
      cin >> u >> v;
      inDegree[v]++;
      edge[u].push_back(v);
    }
    queue<int> q;
    for (int i = 1; i <= N; i++)
      if (inDegree[i] == 0)
        q.push(i);
    ans = cost;
    for (int i = 1; i <= N; i++) {
      int node = q.front();
      q.pop();
      for (int next : edge[node]) {
        ans[next] = max(ans[next], ans[node] + cost[next]);
        if (--inDegree[next] == 0)
          q.push(next);
      }
    }
    cin >> W;
    cout << ans[W] << '\n';
  }
  return 0;
}

 

728x90
반응형