1916 - 최소비용 구하기
본문
$N$개의 도시가 있다. 그리고 한 도시에서 출발하여 다른 도시에 도착하는 $M$개의 버스가 있다. 우리는 $A$번째 도시에서 $B$번째 도시까지 가는데 드는 버스 비용을 최소화 시키려고 한다. $A$번째 도시에서 $B$번째 도시까지 가는데 드는 최소비용을 출력하여라. 도시의 번호는 $1$부터 $N$까지이다.
입력
첫째 줄에 도시의 개수 $N$($1 \leq N \leq 1\,000$)이 주어지고 둘째 줄에는 버스의 개수 $M$($1 \leq M \leq 100\,000$)이 주어진다. 그리고 셋째 줄부터 $M+2$줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그 버스의 출발 도시의 번호가 주어진다. 그리고 그 다음에는 도착지의 도시 번호가 주어지고 또 그 버스 비용이 주어진다. 버스 비용은 0보다 크거나 같고, 100000보다 작은 정수이다.
그리고 $M+3$째 줄에는 우리가 구하고자 하는 구간 출발점의 도시번호와 도착점의 도시번호가 주어진다. 출발점에서 도착점을 갈 수 있는 경우만 입력으로 주어진다.
출력
첫째 줄에 출발 도시에서 도착 도시까지 가는데 드는 최소 비용을 출력한다.
제한
시간 제한 | 메모리 제한 |
---|---|
1sec | 128MB |
풀이
간선의 가중치가 음수가 없는 그래프에서, 시작점이 주어지고, 도착점까지의 최단거리를 찾으라고 한다면 다익스트라 알고리즘이 가장 먼저 떠오른다. 다익스트라를 방해하는 다른 조건이 있는가 봤더니, 딱히 그런 것도 없다. (정점의 수가 적고, 별다른 조건이 없음)
그래서, 이 문제는 다익스트라의 기본형 문제라고 말할 수 있을 것 같다. 자세한 설명은 참고쪽을 보자.
- 참고 알고리즘 : 다익스트라
코드
사용 언어 : C
최종 수정일 : 2023 / 3 / 20
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
#include <stdio.h>
typedef struct Node {
int idx;
int dist;
} ND;
const int INF = 987654321;
#define MAX_IDX (1000 + 1)
int grid[MAX_IDX][MAX_IDX];
int n;
#define min(a, b) (((a) > (b)) ? (b) : (a))
void grid_init() {
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
grid[i][j] = INF;
}
}
return;
}
ND heap[MAX_IDX * MAX_IDX + 1];
int top;
void push(ND x) {
heap[++top] = x;
int a = top;
while (a > 1) {
if (heap[a / 2].dist > x.dist) {
heap[a] = heap[a / 2];
heap[a / 2] = x;
a /= 2;
} else {
break;
}
}
return;
}
ND pop() {
ND node = heap[1];
heap[1] = heap[top--];
int i = 1, tp = 2;
while (tp < top) {
tp += (heap[tp].dist > heap[tp + 1].dist);
if (heap[i].dist <= heap[tp].dist) {
break;
}
ND temp = heap[tp];
heap[tp] = heap[i], heap[i] = temp;
i = tp, tp *= 2;
}
return node;
}
int ret[MAX_IDX];
void dijkstra(int s) {
for (int i = 1; i <= n; ++i) {
if (i == s) {
ret[i] = 0;
} else {
ret[i] = INF;
}
push((ND){i, ret[i]});
}
while (top > 0) {
ND cur = pop();
if (cur.dist <= ret[cur.idx]) {
for (int i = 1; i <= n; ++i) {
if (grid[cur.idx][i] < INF) {
if (ret[i] > cur.dist + grid[cur.idx][i]) {
ret[i] = cur.dist + grid[cur.idx][i];
push((ND){i, ret[i]});
}
}
}
}
}
return;
}
int main() {
scanf("%d", &n);
grid_init();
int m;
scanf("%d", &m);
while (m--) {
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
grid[a][b] = min(grid[a][b], c);
}
int s, e;
scanf("%d %d", &s, &e);
dijkstra(s);
printf("%d", ret[e]);
return 0;
}