먼저 입력으로 주어지는 건설 순서대로 그래프를 만든다. 필자는 역순으로 탐색할 계획이었기 때문에 X, Y 를 입력받았으면 Y정점에서 X정점으로 가는 간선을 연결하였다.
그래프를 연결했으면 승리를 위한 건물을 시작정점으로 하는 깊이 우선 탐색을 수행하는데, 현재 정점의 건물까지 짓는데 걸리는 시간은 (현재 정점에서 건물을 짓는 시간 + 현재 정점에서 갈 수 있는 정점의 건물을 짓는데 걸리는 시간들 중 가장 큰 값) 이므로 이를 그대로 구현해주면 된다.
추가로 이미 계산한 정점을 다시 호출하는 경우가 많으면 시간복잡도가 커지게 되므로 동적 계획법의 메모이제이션 기법을 통해 한번 계산한 정점의 최소 시간을 저장하여 중복되는 연산을 최소화해야 한다.
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
int N, K;
vector<int> adj[1001];
vector<int> weight(1001);
int memo[1001];
int dfs(int start) {
int& ret = memo[start];
if (ret != -1) return ret;
ret = 0;
for (int i = 0; i < adj[start].size(); i++) {
int next = adj[start][i];
ret = max(ret, dfs(next));
}
ret += weight[start];
return ret;
}
int main(void) {
int tc;
cin >> tc;
while (tc--) {
memset(memo, -1, sizeof(memo));
for (int i = 0; i < 1001; i++)
adj[i].clear();
cin >> N >> K;
for (int i = 1; i <= N; i++)
cin >> weight[i];
for (int i = 0; i < K; i++) {
int a, b;
cin >> a >> b;
adj[b].push_back(a);
}
int W;
cin >> W;
cout << dfs(W) << endl;
}
return 0;
}
알고리즘 200일 프로젝트 - 166 day
'알고리즘 > BOJ' 카테고리의 다른 글
백준 2146번: 다리 만들기 (0) | 2020.09.22 |
---|---|
백준 5014번: 스타트링크 (0) | 2020.09.22 |
백준 7562번: 나이트의 이동 (0) | 2020.09.21 |
백준 2589번: 보물섬 (0) | 2020.09.21 |
백준 16234번: 인구 이동 (0) | 2020.09.21 |