Doby's Lab

백준 1005번: ACM Craft (C++) 본문

PS/BOJ

백준 1005번: ACM Craft (C++)

도비(Doby) 2022. 3. 9. 22:28

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

 

1005번: ACM Craft

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

www.acmicpc.net

언뜻 보기에는 최단 경로를 구하는 문제인 듯해 보이지만 간선이 아닌 노드에 건물의 시간 값이 들어있기 때문에 최단 경로 문제가 아니다.

어떤 한 노드로 가는 길에 건물들을 다 짓는 데 걸리는 시간을 구하는 문제다.

건물을 짓는 데에는 순서가 있고, 이 순서를 코드로 짜야하는데 이 시점에서 Topological Sort를 떠올릴 수 있다.

 

문제에 나와있는 예시처럼 1번에서 4번 건물까지 지으려 할 때,

1번 건물에서 10초

2번 건물에서 1초, 3번 건물에서 100초

4번 건물에서 10초

가 소요된다.

 

1, 2, 3, 4 모든 건물을 지어야 하기 때문에 1번 건물 (10초) + 3번 건물 (100초) + 4번 건물 (10초)

>> 총 120초가 걸린다.

여기서 2번 건물이 포함되지 않은 이유는 3번 건물을 100초 동안 지을 때, 이미 2번 건물은 1초 만에 완성되었기 때문이다.

 

즉, 각 노드로 가면서 해당 노드까지 건물을 지은 시간을 갱신해주되 갱신될 수 있는 최댓값을 갱신하면 된다.

노드에서 노드로 가는 방식은 Topological Sort를 이용하면서 구현한다.

 

[AC 코드]

#include <iostream>
#include <vector>
#include <queue>
#define MAX 1001
#define INF 987654321
using namespace std;

int T;
int n, k;
int delay[MAX];
int inDegree[MAX];
vector<int> adj[MAX];
vector<int> result;

void init() {
    for (int i = 1; i <= n; i++) {
        delay[i] = 0;
        inDegree[i] = 0;
        while (!adj[i].empty()) {
            adj[i].pop_back();
        }
    }

    return;
}

void topologicalSort(int node) {
    vector<int> dist(n + 1, 0);
    queue<int> q;

    for (int i = 1; i <= n; i++) {
        if (inDegree[i] == 0) {
            q.push(i);
            dist[i] = delay[i];
        }
    }

    while (!q.empty()) {
        int now = q.front();

        q.pop();
        for (int i = 0; i < adj[now].size(); i++) {
            int next = adj[now][i];

            dist[next] = max(dist[next], dist[now] + delay[next]);
            //cout << dist[next] << '\n';
            inDegree[next] -= 1;
            if (inDegree[next] == 0) {
                q.push(next);
                //cout << next << ' ';
            }
        }
    }

    result.push_back(dist[node]);
}

int main()
{
    cin >> T;
    for (int t = 0; t < T; t++) {
        cin >> n >> k;
        for (int i = 1; i <= n; i++) {
            cin >> delay[i];
        }

        for (int i = 0; i < k; i++) {
            int a, b;
            cin >> a >> b;
            inDegree[b]++;
            adj[a].push_back(b);
        }

        int w;
        cin >> w;
        topologicalSort(w);

        init();
    }

    for (int i = 0; i < result.size(); i++) {
        cout << result[i] << '\n';
    }

    return 0;
}
728x90