일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 영상처리
- 삼성역량테스트
- 삼성코딩테스트
- 임베디드 딥러닝
- sort
- BFS
- 코딩테스트
- dfs문제
- 포스코 AI교육
- 초소형머신러닝
- 알고리즘
- 포스코 교육
- 코테
- 삼성역테
- tflite
- tinyml
- bfs문제
- 코테 문제
- 딥러닝
- TensorFlow Lite
- dfs
- 삼성코테
- DP
- 그리디
- 포스코 ai 교육
- DP문제
- 자료구조
- 컴퓨팅사고
- 다이나믹프로그래밍
- MCU 딥러닝
- Today
- Total
코딩뚠뚠
[백준문제풀이] 1516 게임 개발 본문
풀이일시 : 2020-08-19
문제 :
숌 회사에서 이번에 새로운 전략 시뮬레이션 게임 세준 크래프트를 개발하기로 하였다. 핵심적인 부분은 개발이 끝난 상태고, 종족별 균형과 전체 게임 시간 등을 조절하는 부분만 남아 있었다.
게임 플레이에 들어가는 시간은 상황에 따라 다를 수 있기 때문에, 모든 건물을 짓는데 걸리는 최소의 시간을 이용하여 근사하기로 하였다. 물론, 어떤 건물을 짓기 위해서 다른 건물을 먼저 지어야 할 수도 있기 때문에 문제가 단순하지만은 않을 수도 있다. 예를 들면 스타크래프트에서 벙커를 짓기 위해서는 배럭을 먼저 지어야 하기 때문에, 배럭을 먼저 지은 뒤 벙커를 지어야 한다. 여러 개의 건물을 동시에 지을 수 있다.
편의상 자원은 무한히 많이 가지고 있고, 건물을 짓는 명령을 내리기까지는 시간이 걸리지 않는다고 가정하자.
입력:
첫째 줄에 건물의 종류 수 N(1 ≤ N ≤ 500)이 주어진다. 다음 N개의 줄에는 각 건물을 짓는데 걸리는 시간과 그 건물을 짓기 위해 먼저 지어져야 하는 건물들의 번호가 주어진다. 건물의 번호는 1부터 N까지로 하고, 각 줄은 -1로 끝난다고 하자. 각 건물을 짓는데 걸리는 시간은 100,000보다 작거나 같은 자연수이다.
ex)
5 //5개의 건물
10 -1 // 1번 건물은 10시간이 걸린다.
10 1 -1 // 2번 건물은 10시간이 걸리고 1번 건물이 선행되어야 한다.
4 1 -1 // 3번건물은 4시간이 걸리고 1번건물이 선행되어야한다.
4 3 1 -1 // 4번건물은 3시간이 걸리고 3번건물과 1번건물이 선행되어야한다.
3 3 -1 // 5번건물은 3시간이 걸리고 3번건물이 선행되어야한다.
출력:
N개의 각 건물이 완성되기까지 걸리는 최소 시간을 출력한다.
ex)
10
20
14
18
17
풀이 :
SCC를 이용한다
선행 건물이 주어지므로 위상정렬을 이용한다.
모든 정점이 수행될수있는 최소시간을 출력하는 것이므로 단순히 임계경로를 출력하면된다
간선이 연결되는 순간을 기준으로 현재보다 더 오래걸린다면 계속하여 갱신하는 방식으로..
#include <vector>
#include <iostream>
#include <queue>
#define MAX 501
using namespace std;
int n, inDegree[MAX], time[MAX], result[MAX];
vector<int> a[MAX];
void topologySort() {
queue<int> q;
for (int i = 1; i <= n; i++) {
if (inDegree[i] == 0) { //진입차수가 0인거 다 큐에 넣는다.
result[i] = time[i];
q.push(i);
}
}
for (int i = 1; i <= n; i++) {
int x = q.front();
q.pop();
for (int i = 0; i < a[x].size(); i++) { //a[x]의 사이즈 즉 인접노드만큼
int y = a[x][i]; //인접노드 y
result[y] = max(result[y], result[x] + time[y]); //최댓값을 갱신해주는것
if (--inDegree[y] == 0) q.push(y); //진입차수를 줄여주고 0이되면 push
}
}
for (int i = 1; i <= n; i++) {
printf("%d\n", result[i]);
}
}
int main(void) {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> time[i]; //i번째 건물 짓는데에는 time[i]의 시간이 걸린다.
while (1) {
int x;
cin >> x; //선행되어야 할 건물번호는 x
if (x == -1) break;
inDegree[i]++; //그 x의 진입차수를 증가시켜놓는다.
a[x].push_back(i); //선행건물 x를 지어야 i를 지을수있음 a[x]의 연결노드와 사이즈를 위해 생성
}
}
topologySort();
}
참고자료
'알고리즘 문제풀이 > 백준문제풀이' 카테고리의 다른 글
[백준문제풀이] 2188 축사배정 (0) | 2020.12.30 |
---|---|
[백준문제풀이] 1948 임계경로 (0) | 2020.12.30 |
[백준문제풀이] 2252 줄 세우기 (0) | 2020.12.29 |
[백준문제풀이] 15852 타일 채우기 3 (0) | 2020.12.29 |
[백준문제풀이] 2133 타일 채우기 (0) | 2020.12.29 |