알고리즘/백준

BOJ2637/ C++

내이름은 킹햄찌 2022. 1. 10. 00:02

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

 

2056번: 작업

수행해야 할 작업 N개 (3 ≤ N ≤ 10000)가 있다. 각각의 작업마다 걸리는 시간(1 ≤ 시간 ≤ 100)이 정수로 주어진다. 몇몇 작업들 사이에는 선행 관계라는 게 있어서, 어떤 작업을 수행하기 위해

www.acmicpc.net

백준 온라인저지 2056번 문제입니다. 

위상정렬을 이용해서 풀었습니다.

 

#include<iostream>
#include<vector>
#include<queue>
#define MAX 10001


using namespace std;

int N, M;
int sol;
int indegree[MAX];
int time[MAX];
vector<pair<int,int>> adj[MAX];

int max(int a, int b) {	return a > b ? a : b; }

void Input() {
	int a;
	cin >> N;
	for (int i = 1; i <= N; i++) {
		cin >> time[i];
		cin >> M;
		while (M--) {
			cin >> a;
			indegree[i]++;
			adj[a].push_back({ i,time[i] });
		}
	}
}

void solution() {
	queue<int>q;
	for (int i = 1; i <= N; i++) {
		if (indegree[i]==0) {
			q.push(i);
		}
	}
	while (!q.empty()) {
		int current = q.front();
		q.pop();
		sol = max(sol, time[current]);
		for (auto itor : adj[current]) {
			int next = itor.first;
			int next_time = itor.second;
			time[next] = max(time[next], time[current] + next_time);
            //작업을 할때 선행작업이 2개 이상일때 그 중 가장 오래걸리는 작업이 끝나야
            //현제 작업을 할 수 있기때문에 가장 오래걸리는 작업의 시간을 찾아야함

			if (--indegree[next] == 0) {
				q.push(next);
			}
		}
	}
    cout << sol;
}

int main(void) {
	Input();
	solution();
}
/*
1번 반례
작업의 우선순의가 없을때
7
5 0
3 0
6 0
1 0
8 0
4 0
2 0
8

2번 반례
큐에 넣기전에 max 비교를 하게되면 이전 작업이 오래 걸리는 케이스에서 문제발생함
5
6 0
3 0
3 2 1 2
1 1 1
1 2 3 4

*/

아이디어

이전에 풀었던 백준 1516 문제와 비슷함 그런데 추가적으로 신경써야하는 것은 선행 작업이 없을 수도 있다는 것임

그래서 각 작업마다의 값을 비교하여 최댓값을 sol에 저장하여 마지막에는 sol을 출력하도록함