백준 1005 - ACM Craft
1 분 소요
백준 1005 문제 바로가기
풀이
- 정점을 작업(task)이라고 했을 때, indegree(진입차수)가 0이 아닌 작업들은 선행되어야 하는 다른 작업들이 모두 끝나야 비로소 수행될 수 있다.
- 따라서 초기에 indegree(진입차수)가 0인 모든 정점을 큐에 넣는다.
- 큐에서 꺼낸 정점(now)이 향하고 있는 정점(next)의 indegree를 1감소시켰을 때, 값이 0이면 큐에 넣는다.
- 다음 정점(next)에 도달하는데 소요되는 시간이 현재(now) 위치의 정점에서 소요되는 시간보다 크도록 갱신한다.
소스 코드
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
int T;
int N;//건물 수
int K;//건설 순서 규칙 개수
int initTime[1001];
int totalTime[1001];
vector<int> adj[1001];
int indegree[1001];
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
cin >> T;
for (int tc = 0; tc != T; ++tc) {
cin >> N >> K;
for (int num = 1; num <= N; ++num) {
cin >> initTime[num]; // num 건물을 짓는데 소요되는 시간
totalTime[num] = initTime[num];
// init
adj[num].clear();
}
for (int i = 0, X, Y; i != K; ++i) {
cin >> X >> Y; // X를 지은 후 Y를 짓는것이 가능
adj[X].push_back(Y);
++indegree[Y];
}
queue<int> q;
for (int num = 1; num <= N; ++num) {
if (indegree[num] == 0) {
q.push(num);
}
}
while (!q.empty()) {
int now = q.front();
q.pop();
for (int next : adj[now]) {
if (--indegree[next] == 0) {
q.push(next);
}
totalTime[next] = max(totalTime[next], totalTime[now] + initTime[next]);
}
}
int W;
cin >> W;
// 건물 W를 건설완료 하는데 드는 최소 시간
cout << totalTime[W] << '\n';
}
return 0;
}