본문 바로가기

알고리즘/백준

백준 1516 게임 개발

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

 

1516번: 게임 개발

첫째 줄에 건물의 종류 수 N(1 ≤ N ≤ 500)이 주어진다. 다음 N개의 줄에는 각 건물을 짓는데 걸리는 시간과 그 건물을 짓기 위해 먼저 지어져야 하는 건물들의 번호가 주어진다. 건물의 번호는 1부

www.acmicpc.net

 

위상정렬 문제다.

 

차이가 있다면 '시간'이라는 변수가 추가된 것!

 

보통은 'C건물이 완성되려면 A건물과 B건물이 완성되어야 합니다' 라는 문제조건에 따라 

 

inedge의 개수만 세면 되는데 이 문제는 '시간'이 기준이어서 A건물과 B건물이 완성되는 시간 모두를 고려하는 게 아니라

 

둘 중 더 늦게 완성되는 건물의 완성 시간을 기준으로 잡아야 한다.

 

즉 Queue가 아니라 priority Queue를 써야 한다.

/* 게임 개발 */

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

int N, in[500 + 1], time[500 + 1], precedence[500 + 1];
bool is_visit[500 + 1];
vector<int> building[500 + 1];

int main(void) {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);

	cin >> N;
	for (int i = 1; i <=N; i++) {
		cin >> time[i];
		while (true) {
			int temp;
			cin >> temp;

			if (temp == -1) {
				break;
			}
			
			building[temp].push_back(i);
			in[i]++;
		}
	}

	priority_queue<pair<int,int>> history;
	for (int i = 1; i <= N; i++) {
		if (in[i] == 0) {
			is_visit[i] = true;
			history.push({ time[i], i });
		}
	}
	
	while (!history.empty()) {	
		int current_building = history.top().second;
		int current_time = history.top().first;
		history.pop();

		for (auto i : building[current_building]) {
			if (is_visit[i]) continue;
			precedence[i] = max(precedence[i], current_time);
			in[i]--;
			if (in[i] == 0){
				is_visit[i] = true;
				time[i] += precedence[i];
				history.push({ time[i], i });
			}
		}
	}

	for (int i = 1; i <= N; i++) {
		cout << time[i] << '\n';
	}
	return 0;
}

'알고리즘 > 백준' 카테고리의 다른 글

백준 1202 보석 도둑  (0) 2020.08.03
백준 1517 버블 소트  (0) 2020.08.03
백준 9935 문자열 폭발  (0) 2020.08.02
백준 9019 DSLR  (0) 2020.08.01
백준 5214 환승  (0) 2020.07.31