728x90
오답 노트 & 새로 알게 된 점
해당 문제는 다익스트라를 이용하여 풀면 되는데,
다른 문제와 다른 점은 최소 경로 값을 출력하는 것이 아니라
가장 먼저 거쳐야 할 노드를 출력하는 것이다.
전체적인 풀이를 말하자면
1 ~ N번 노드까지 다익스트라를 구한 뒤,
각 n번 노드마다 parent를 구하여 정답 배열에 넣어준다.
값을 출력할 때는 행과 열이 같은 지점(대각선) 에는 "-" 을 넣어준다.
즉, 1 - 3 - 2가 최소 경로일 때, (1,2)의 값은 3이 된다.
1 ~ N번 노드까지 다익스트라를 이용하여 최소 경로를 구하면서,
최소 경로가 갱신될 때마다 즉,
if(dist[node.idx] != node.dist) continue;
if(dist[node.idx] + in.wei >= dist[in.to]) continue;
dist[in.to] = dist[node.idx] + in.wei;
pq.offer(new Node(in.to, dist[in.to]));
parent[in.to] = node.idx;
위 조건을 만족할 때마다 parent 값을 변경시켜주면 된다.
parent[i] = j 일 때,
j번 노드를 가기 전에 i번 노드를 거쳐가는 것이다.
즉, j번 노드가 i번 노드의 부모이다.
부모 값을 찾는 방법
static int find(int v, int start) {
if(parent[v] == start) return v;
return find(parent[v], start);
}
find 메서드를 이용하여 부모를 찾는다.
부모는 출발점에서 가장 먼저 거쳐야 하는 노드를 구한다.
1 - 3 - 2에서
parent[1] = 1
parent[2] = 3
parent[3] = 1
이 되고,
find 메서드를 통해 2번 노드는 3번 노드가 반환되는 것을 알 수 있다.
코드
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
import java.io.*;
import java.util.*;
public class Main {
static int atoi(String str) {
return Integer.parseInt(str);
}
static int parent[];
static ArrayList<Info> A[];
static int N, M;
static int dist[];
static int ans[][];
public static void main(String[] args) throws IOException {
input();
pro();
}
static void pro() {
for (int i = 1; i <= N; i++) {
dijkstra(i);
}
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if(i == j) {
System.out.print("-" + " ");
continue;
}
System.out.print(ans[i][j] + " ");
}
System.out.println();
}
}
static void dijkstra(int start) {
PriorityQueue<Node> pq = new PriorityQueue<>((o1, o2)->{
return o1.dist - o2.dist;
});
Arrays.fill(dist, Integer.MAX_VALUE);
for(int i = 1; i <= N; i++) parent[i] = i;
pq.offer(new Node(start, 0));
dist[start] = 0;
while (!pq.isEmpty()) {
Node node = pq.poll();
for (Info in : A[node.idx]) {
if(dist[node.idx] != node.dist) continue;
if(dist[node.idx] + in.wei >= dist[in.to]) continue;
dist[in.to] = dist[node.idx] + in.wei;
pq.offer(new Node(in.to, dist[in.to]));
parent[in.to] = node.idx;
}
}
for (int i = 1; i <= N; i++) {
ans[start][i] = find(i, start);
}
}
static int find(int v, int start) {
if(parent[v] == start) return v;
return find(parent[v], start);
}
static void input() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = atoi(st.nextToken());
M = atoi(st.nextToken());
ans = new int[N+1][N+1];
dist = new int[N+1];
parent = new int[N+1];
A = new ArrayList[N+1];
for (int i = 0; i <= N; i++) A[i] = new ArrayList<>();
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int from = atoi(st.nextToken());
int to = atoi(st.nextToken());
int wei = atoi(st.nextToken());
A[from].add(new Info(to, wei));
A[to].add(new Info(from, wei));
}
}
static class Info{
int to, wei;
public Info(int to, int wei) {
this.to = to;
this.wei = wei;
}
}
static class Node{
int idx, dist;
public Node(int idx, int dist) {
this.idx = idx;
this.dist = dist;
}
}
}
|
cs |
728x90
'BOJ(Java)' 카테고리의 다른 글
자바(백준) 16637 괄호 추가하기 (0) | 2022.01.02 |
---|---|
자바(백준) 1238 파티 (0) | 2021.12.29 |
자바(백준) 1261 알고스팟 (0) | 2021.12.28 |
자바(백준) 23629 이 얼마나 끔찍하고 무시무시한 수식이니 (0) | 2021.12.27 |
자바(백준) 10423 전기가 부족해 (0) | 2021.12.22 |