728x90
문제 링크
풀이 아이디어
작업을 완료하기 위해 어떤 작업이 먼저 수행되어야 하는지를 파악해야 하므로
당연히 위상정렬 문제이다.
친절하게 각 줄의 두번째 int 값으로 indegree(먼저 수행되어야 하는 노드, 즉 조상노드의 개수)가 써져 있으므로
그대로 써먹으면 된다. (numOfancestor)
dp는 바로 이 '선행되는 조상노드의 실행 시간의 최댓값' 을 파악하기 위해 사용된다.
쉽게 예를 들어보겠다.
a라는 작업이 5분
b라는 작업이 10분
c라는 작업이 7분이 걸린다고 해보자.
이때 a는 반드시 b,c 작업이 끝나야 작업이 가능하다는 조건이 붙었다고 해보면
a를 끝낼 수 있는 최단 시간은 15분이다.
왜냐하면 b,c 중에서 더 작업 시간이 긴 b의 작업시간이 10분이기 때문이다.
(문제의 조건에 의해 b,c는 서로 연관이 없으므로 동시 수행이 가능)
코드에 해당하는 부분은 dp[next] = max(dp[next],dp[now]+t[next]); 이다.
next에 a가 들어가고 now 에 b,c가 들어가는 구조의 간단한 메모이제이션이다.
하지만 최댓값 기록을 위해,, 반드시 필요한 단계이다.
좋은 문제였다고 생각한다.
코드
#include <bits/stdc++.h>
using namespace std;
int n,answer;
int t[10001];
int dp[10001];
int numOfancestor[10001];
vector<int> A[10001];
int main(void){
queue<int> q;
cin>>n;
for(int i=1; i<=n; i++){
int x;
cin>>t[i]>>x;
dp[i]=t[i];
numOfancestor[i]=x;
if(x!=0){
for(int j=0; j<x; j++){
int pre;
cin>>pre;
A[pre].push_back(i);
}
}
}
for(int i=1; i<=n; i++)
if(numOfancestor[i]==0)
q.push(i);
while(!q.empty()){
int now = q.front();
cout<<now<<" ";
q.pop();
for(int i=0; i<A[now].size(); i++){
int next = A[now][i];
dp[next] = max(dp[next],dp[now]+t[next]);
numOfancestor[next]--;
if(numOfancestor[next]==0)
q.push(next);
}
}
for(int i=1; i<=n; i++)
answer = max(answer,dp[i]);
cout<<answer;
}
'알고리즘 > 백준' 카테고리의 다른 글
백준 1647 도시 분할 계획 : 전형적인 MST + 부모 동일 유무 파악시 주의할 점 (0) | 2021.01.19 |
---|---|
백준 1516 게임 개발 - 위상정렬과 dp가 함께 쓰이는 문제(2) (0) | 2021.01.16 |
백준 4195 친구 네트워크 - map과 union-find 혼합 문제 (0) | 2021.01.14 |
백준 1976 여행가자 - 2차원 array 형태로 데이터 주어질 때 효과적인 union find (0) | 2021.01.14 |
백준 2533 사회망 서비스 - 가장 쉽고 자세한 트리 dp로 푸는 방법 (0) | 2021.01.14 |