Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- BFS
- 이분 탐색
- MySQL
- SCC
- 위상정렬
- kruskal
- MST
- 구현
- 투 포인터
- Linux
- springdoc
- 알고리즘
- disjoint set
- tarjan
- Meet in the middle
- 페르마 소정리
- 누적 합
- Java
- miller-rabin
- concurreny
- 위상 정렬
- kapt
- union-find
- 분리 집합
- 그래프
- spring boot
- DP
- BindingAdapter
- 백트래킹
- DFS
Archives
- Today
- Total
기맹기 개발 블로그
[BOJ 1005] ACM Craft (Java) 본문
BOJ 1005 ACM Craft
난이도 : 골드 3
https://www.acmicpc.net/problem/1005
1005번: ACM Craft
첫째 줄에는 테스트케이스의 개수 T가 주어진다. 각 테스트 케이스는 다음과 같이 주어진다. 첫째 줄에 건물의 개수 N과 건물간의 건설순서 규칙의 총 개수 K이 주어진다. (건물의 번호는 1번부
www.acmicpc.net
전략
단순 위상정렬해서 순서만 중요한 것이 아니라
소요시간을 계산해야 한다.
이는 다음 노드 탐색 과정에서 메모이제이션을 이용하여 최댓값을 저장하는 방식을 사용했다.
단순히 값을 저장하면 되는 것처럼 보이지만, 여러 경로가 합쳐질 때는 최댓값을 이용하여야 결과를 얻을 수 있다.
시행착오
메모이제이션을 큐에서 꺼낸 위치에서 실행했는데, 이미 이전 노드 dp가 끝난 이후라서 틀린 결과가 나왔다.
따라서 큐에서 꺼낸 노드가 가리키는 노드들에 대해서 dp를 해줘야 한다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.PriorityQueue;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T, N, K;
T = Integer.parseInt(br.readLine());
for (int t = 0; t < T; t++) {
String[] line = br.readLine().split(" ");
N = Integer.parseInt(line[0]);
K = Integer.parseInt(line[1]);
Node[] nodes = new Node[N + 1];
line = br.readLine().split(" ");
for (int i = 1; i <= N; i++)
nodes[i] = new Node(i, Integer.parseInt(line[i - 1]));
for (int i = 0; i < K; i++) {
line = br.readLine().split(" ");
int from = Integer.parseInt(line[0]);
int to = Integer.parseInt(line[1]);
nodes[from].link.add(nodes[to]);
nodes[to].linked++;
}
int dest = Integer.parseInt(br.readLine());
System.out.println(topologySort(nodes, dest));
}
br.close();
}
static int topologySort(final Node[] nodes, int dest) {
final int N = nodes.length - 1;
PriorityQueue<Node> pq = new PriorityQueue<>((n1, n2) -> n2.cost - n1.cost);
int[] dp = new int[N + 1];
for (int i = 1; i <= N; i++) {
dp[i] = nodes[i].cost;
if (nodes[i].linked == 0)
pq.offer(nodes[i]);
}
for (int i = 0; i < N; i++) {
if (pq.isEmpty())
break;
Node cur = pq.poll();
if (cur.num == dest)
break;
for (Node next : cur.link) {
dp[next.num] = Math.max(dp[next.num], dp[cur.num] + next.cost);
if (--next.linked == 0)
pq.offer(next);
}
}
return dp[dest];
}
static class Node {
int num;
int cost;
int linked = 0;
ArrayList<Node> link = new ArrayList<>();
Node(int num, int cost) {
this.num = num;
this.cost = cost;
}
}
}
깨달은 점
dp의 세계는 무궁무진한 것 같다.
'PS' 카테고리의 다른 글
[BOJ 9466] 텀 프로젝트 (Java) (0) | 2022.09.08 |
---|---|
[BOJ 7579] 앱 (Java) (0) | 2022.09.07 |
[BOJ 1766] 문제집 (Java) (0) | 2022.08.31 |
[BOJ 3665] 최종 순위 (Java) (0) | 2022.08.31 |
[BOJ 2252] 줄 세우기 (Java) (0) | 2022.08.30 |