ALGORITHM/BOJ
[BOJ] 11779 최소비용 구하기2
0298
2022. 6. 29. 23:01
https://www.acmicpc.net/problem/11779
11779번: 최소비용 구하기 2
첫째 줄에 도시의 개수 n(1≤n≤1,000)이 주어지고 둘째 줄에는 버스의 개수 m(1≤m≤100,000)이 주어진다. 그리고 셋째 줄부터 m+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그 버스
www.acmicpc.net
2022-06-29
1) ArrayList 들고 다니면서
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
|
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main11779_BufferedReader {
static class Route implements Comparable<Route>{
int num;
int cost;
List<Integer> bus = new ArrayList<>();
public Route(int num, int cost, List<Integer> bus) {
this.num = num;
this.cost = cost;
this.bus = bus;
}
@Override
public int compareTo(Route o) {
return this.cost - o.cost;
}
}
public static int N, M;
public static List<List<Route>> list;
public static List<Integer> answer;
public static PriorityQueue<Route> pq;
public static int[] dist;
public static void solve(int start, int end) {
pq = new PriorityQueue<>();
pq.add(new Route(start, 0, answer));
dist[start] = 0;
boolean[] vtd = new boolean[N+1];
while(!pq.isEmpty()) {
Route r = pq.poll();
if(vtd[r.num]) continue;
vtd[r.num] = true;
for(Route ro: list.get(r.num)) {
if(dist[ro.num] > dist[r.num] + ro.cost) {
dist[ro.num] = dist[r.num] + ro.cost;
List<Integer> tmp = new ArrayList<>(r.bus);
tmp.add(ro.num);
if(ro.num == end) {
answer = tmp;
}
pq.add(new Route(ro.num, dist[ro.num], tmp));
}
}
}
}
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(bf.readLine());
N = Integer.parseInt(st.nextToken());
st = new StringTokenizer(bf.readLine());
M = Integer.parseInt(st.nextToken());
list = new ArrayList<>();
dist = new int[N+1];
for(int i = 0; i <= N; i++) {
list.add(new ArrayList<>());
dist[i] = 987654321;
}
for(int i = 0; i < M; i++) {
st = new StringTokenizer(bf.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
list.get(a).add(new Route(b, c, new ArrayList<>()));
}
st = new StringTokenizer(bf.readLine());
int start = Integer.parseInt(st.nextToken());
int end = Integer.parseInt(st.nextToken());
answer = new ArrayList<>();
answer.add(start);
solve(start, end);
System.out.println(dist[end]);
System.out.println(answer.size());
StringBuilder sb = new StringBuilder();
for(int i = 0; i < answer.size(); i++) sb.append(answer.get(i)).append(" ");
System.out.println(sb.toString());
}
}
|
cs |
2) Visited 경로
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
|
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main11779_BufferedReader_visited {
static class Route implements Comparable<Route>{
int num;
int cost;
public Route(int num, int cost) {
this.num = num;
this.cost = cost;
}
@Override
public int compareTo(Route o) {
return this.cost - o.cost;
}
}
public static int N, M;
public static List<List<Route>> list;
public static PriorityQueue<Route> pq;
public static int[] dist, visited;
public static void solve(int start, int end) {
pq = new PriorityQueue<>();
pq.offer(new Route(start, 0));
dist[start] = 0;
boolean[] vtd = new boolean[N+1];
while(!pq.isEmpty()) {
Route r = pq.poll();
if(vtd[r.num]) continue;
vtd[r.num] = true;
for(Route ro: list.get(r.num)) {
if(dist[ro.num] > dist[r.num] + ro.cost) {
dist[ro.num] = dist[r.num] + ro.cost;
pq.offer(new Route(ro.num, dist[ro.num]));
visited[ro.num] = r.num; // visited[cur] = previous
}
}
}
}
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(bf.readLine());
N = Integer.parseInt(st.nextToken());
st = new StringTokenizer(bf.readLine());
M = Integer.parseInt(st.nextToken());
list = new ArrayList<>();
dist = new int[N+1];
visited = new int[N+1];
for(int i = 0; i <= N; i++) {
list.add(new ArrayList<>());
dist[i] = 987654321;
}
for(int i = 0; i < M; i++) {
st = new StringTokenizer(bf.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
list.get(a).add(new Route(b, c));
}
st = new StringTokenizer(bf.readLine());
int start = Integer.parseInt(st.nextToken());
int end = Integer.parseInt(st.nextToken());
solve(start, end);
List<Integer> temp = new ArrayList<>();
int find = end;
while(find > 0) {
temp.add(find);
find = visited[find]; //5 -> 4 -> 1
}
System.out.println(dist[end]);
System.out.println(temp.size());
StringBuilder sb = new StringBuilder();
for(int i = temp.size() - 1; i >= 0; i--) sb.append(temp.get(i)).append(" ");
System.out.println(sb.toString());
}
}
|
cs |
#문제풀이
다익스트라 문제이다.
arraylist를 들고다니면서 체크하는 방식으로 풀었는데, 다른 사람들 풀이를 보니 경로를 저장한 방법을 사용한 사람들이 있어서 해당 방법으로도 풀어보았다.
예를 들어 1 -> 4 -> 5 라는 경로로 이동 했다고 치면, end(5)부터 경로를 거꾸로 가보면 이런식으로 루트를 찾을 수 있다.
visited[5]
ㄴ visited[4]
ㄴ visited[1]