코딩스토리

백준 1005번 - ACM Craft 본문

알고리즘/BOJ 문제 풀이

백준 1005번 - ACM Craft

kimtaehyun98 2021. 1. 1. 19:34

www.acmicpc.net/problem/1005

 

1005번: ACM Craft

첫째 줄에는 테스트케이스의 개수 T가 주어진다. 각 테스트 케이스는 다음과 같이 주어진다. 첫째 줄에 건물의 개수 N 과 건물간의 건설순서규칙의 총 개수 K이 주어진다. (건물의 번호는 1번부

www.acmicpc.net

옛날부터 이문제 한번 풀어보고 싶었는데 골드 3에 dp라 뭔가 엄청 어려울 것 같아서 못풀었었다.

오늘 날잡고 어떻게든 한번 풀어보자 하고 풀어봤다.

 

처음 문제를 봤을때 재귀가 떠올랐다. 이런 문제의 경우 dfs라고 하는게 맞겠지만..

분명 dp와 재귀를 통해 풀 수 있을것 같은데 이게 맞을까 싶어서, 해결법이 맞는지를 한참 고민했다.

 

아무리 봐도 다른 방법은 떠오르지 않아서 그냥 풀었는데 다행히 맞았다.

 

해결법은 다음과 같다.

 

1. 구하고자 하는 노드(문제에서는 건물)의 실행시간을 구하기 위해서 선행 노드들을 모두 방문한다.

2. 1번 과정을 재귀적으로 반복해서 각 노드들의 선행 노드들의 실행시간을 구한 뒤 답을 찾는다.

 

이때 중요한점은 조건을 설정할 때 내가 구하고 싶은 노드만 구한다. 

다시 말해 문제에서 거리를 알 필요가 없는 노드는 방문조차 안한다는 말이다.

 

코드는 다음과 같다.

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
int dist[1004];
vector<int>arr[1004];
int dp[1004];
bool check[1004];
 
int find(int x) {
    if (arr[x].size() == 0return dist[x - 1];
    int max_num = 0;
    for (int i = 0; i < arr[x].size(); i++) {
        int node = arr[x][i];
        if (check[node] == false) {
            dp[node] = find(node);
            check[node] = true;
        }
        max_num = max(max_num, dp[node]);
    }
    return max_num + dist[x - 1];
}
 
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t, n, k, a, b, x;;
    cin >> t;
    while (t--) {
        memset(dist, 0sizeof(dist));
        memset(arr, 0sizeof(arr));
        memset(dp, 0sizeof(dp));
        memset(check, falsesizeof(check));
        cin >> n >> k;
        for (int i = 0; i < n; i++cin >> dist[i];
        for (int i = 0; i < k; i++) {
            cin >> a >> b;
            arr[b].push_back(a);
        }
        cin >> x;
        cout << find(x)<< "\n";
    }
}
cs

재귀함수만 잘 짜준다면 코드 자체는 복잡하지 않다.

'알고리즘 > BOJ 문제 풀이' 카테고리의 다른 글

백준 9251번 - LCS  (0) 2021.01.15
백준 11048번 - 이동하기  (0) 2021.01.06
백준 2056번 - 작업  (0) 2021.01.01
Educational Codeforces Round 98 (Rated for Div. 2) - C번  (0) 2020.12.27
백준 2621번 - 카드게임  (0) 2020.12.27
Comments