(C++) BOJ 백준 1005번 ACM Craft / 위상 정렬(Topology Sort)

2025. 3. 21. 20:01·Algorithm

BOJ.1005 ACM CRAFT 문제

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

문제 설명


  • 문제에서 입력으로 주어지는 건물이 지어지기까지의 최단 시간을 구하는 문제
  • 특정 건물을 짓기전에 먼저 지어야하는 건물의 순서가 주어진다
  • 먼저 지어야 하는 건물들을 지으면서 입력으로 주어지는 W에 해당하는 건물이 지어지기 까지의 시간을 구하면 된다

문제 풀이


  • 이 문제와 같이 순서가 주어지고 먼저 해결해야할 작업이 있을때의 경로에 관한 문제는 위상 정렬(Topology Sort)로 해결할 수 있다.
  • 위상정렬(Topology Sort)는 가장 먼저 시작할 수 있는 일이 담긴 노드를 큐(Queue)에 넣어주고 시작한다.
  • 가장 앞에 있는 노드를 꺼내고 해당 노드와 연결된 간선을 모두 제거한다.
  • 간선들을 제거하면서 먼저 수행되어야할 작업이 담긴 노드가 0개인 노드들에 대해서 다시 큐에 넣어준다. 이 4가지 작업을 반복한다.
  • ACM CRAFT 문제에서는 위상정렬을 수행하면서 특정 노드 A가 있다고 가정해보면, A까지 오기전 작업들중 가장 오래 걸리는 작업의 시간을 저장하며 수행한다.
  • 이때, W까지 오기까지의 저장된 시간에 W건물을 짓는 시간을 더해주면 정답이 나오게 된다.

코드


#include <iostream>
#include <vector>
#include <queue>
using namespace std;
#define FOR(i,N) for(int i=1; i<=N; i++)
int T;
int N, K, W;
int buildTime[1001];
vector<int> buildSeq[1001];
int buildCount[1001];
int completeTime[1001];
void build(queue<pair<int,int>>& q) {
    while(!q.empty()) {
        int cur = q.front().first;
        int curTime = q.front().second;
        if(cur==W) {
            cout << curTime << '\n';
            return;
        }
        q.pop();
        for(int i=0; i<buildSeq[cur].size(); i++) {
            buildCount[buildSeq[cur][i]]--;
            completeTime[buildSeq[cur][i]] = max(completeTime[buildSeq[cur][i]], curTime + buildTime[buildSeq[cur][i]]);
            if(buildCount[buildSeq[cur][i]] == 0) {
                q.push({buildSeq[cur][i], completeTime[buildSeq[cur][i]]});
                buildCount[buildSeq[cur][i]] = -1;
            }
        }
    }
}
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> T;
    while(T--) {
        cin >> N >> K;
        FOR(i,N) {
            cin >> buildTime[i];
            buildCount[i] = 0;
            completeTime[i] = 0;
            buildSeq[i].clear();
        }
        FOR(i,K) {
            int first,second;
            cin >> first >> second;
            buildSeq[first].push_back(second);
            buildCount[second]++;
        }
        cin >> W;
        queue<pair<int,int>> q;
        FOR(i,N) {
            if(buildCount[i] == 0) {
                q.push({i,buildTime[i]});
                completeTime[i] = buildTime[i];
            }
        }
        build(q);
    }
    return 0;
}

'Algorithm' 카테고리의 다른 글

(C++) BOJ 백준 1525 퍼즐 / BFS, unordered_map  (0) 2025.04.02
(C++) BOJ 백준 10942번 펠린드롬?  (0) 2025.03.17
(C++) 백준 1992.쿼드트리  (0) 2025.02.18
(C++) 백준 15591. MooTube  (0) 2025.01.26
(C++) 백준 1068.트리  (0) 2025.01.25
'Algorithm' 카테고리의 다른 글
  • (C++) BOJ 백준 1525 퍼즐 / BFS, unordered_map
  • (C++) BOJ 백준 10942번 펠린드롬?
  • (C++) 백준 1992.쿼드트리
  • (C++) 백준 15591. MooTube
devStudent
devStudent
저의 개발(Development) 공부(Study) 기록을 추적(Tracing) 하는 블로그입니다!
  • devStudent
    Dev_Study_Trace
    devStudent
  • 전체
    오늘
    어제
    • 분류 전체보기 (23)
      • BackEnd (11)
      • DevOps (4)
      • Algorithm (7)
      • DDD 12기 (Server) (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    리버스 프록시
    알고리즘
    boj1068
    NGINX
    http 상태코드
    프록시 실습
    백준 1068번
    docker
    Divide and conquer
    GitHub Actions
    boj 1992
    도커
    yml
    boj
    분할 정복 알고리즘
    devops
    데브 옵스
    쿠버네티스
    백준 1092
    백준
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
devStudent
(C++) BOJ 백준 1005번 ACM Craft / 위상 정렬(Topology Sort)
상단으로

티스토리툴바