[백준 11779] 최소비용 구하기 2 (C#, C++) - soo:bak
작성일 :
문제 링크
설명
시작 도시에서 도착 도시까지 가는 최소 비용과 그 경로를 구하는 문제입니다. 버스 노선마다 비용이 다르고, 한 도시에서 다른 도시로 가는 버스가 여러 개 있을 수 있습니다.
접근법
먼저 다익스트라 알고리즘으로 시작 도시에서 도착 도시까지의 최단 비용을 구합니다. 시작 도시의 비용은 0, 나머지는 무한대로 초기화한 뒤 우선순위 큐를 이용해 비용이 작은 도시부터 처리합니다. 현재 도시를 경유하는 것이 더 저렴하면 해당 도시의 비용을 갱신하고 큐에 추가합니다.
다음으로 경로를 복원하기 위해 비용이 갱신될 때마다 이전 도시를 기록합니다. 예를 들어 도시 3에서 도시 5로 갈 때 비용이 갱신되었다면, 도시 5의 이전 도시로 3을 저장합니다.
이후 도착 도시에서 시작해 기록된 이전 도시를 따라가면 경로를 역순으로 얻을 수 있습니다. 이를 뒤집어 출력하면 시작 도시부터 도착 도시까지의 경로가 됩니다.
Code
C#
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
using System;
using System.Collections.Generic;
namespace Solution {
class Program {
static void Main(string[] args) {
var n = int.Parse(Console.ReadLine()!);
var m = int.Parse(Console.ReadLine()!);
var adj = new List<(int to, int w)>[n + 1];
for (var i = 1; i <= n; i++)
adj[i] = new List<(int, int)>();
for (var i = 0; i < m; i++) {
var parts = Array.ConvertAll(Console.ReadLine()!.Split(), int.Parse);
var a = parts[0];
var b = parts[1];
var c = parts[2];
adj[a].Add((b, c));
}
var se = Array.ConvertAll(Console.ReadLine()!.Split(), int.Parse);
var start = se[0];
var end = se[1];
const int INF = int.MaxValue;
var dist = new int[n + 1];
var prev = new int[n + 1];
Array.Fill(dist, INF);
var pq = new PriorityQueue<int, int>();
dist[start] = 0;
pq.Enqueue(start, 0);
while (pq.Count > 0) {
pq.TryDequeue(out var cur, out var curCost);
if (curCost > dist[cur])
continue;
foreach (var edge in adj[cur]) {
var nxt = edge.to;
var w = edge.w;
var nd = dist[cur] + w;
if (nd < dist[nxt]) {
dist[nxt] = nd;
prev[nxt] = cur;
pq.Enqueue(nxt, nd);
}
}
}
Console.WriteLine(dist[end]);
var path = new Stack<int>();
for (var v = end; v != 0; v = prev[v])
path.Push(v);
Console.WriteLine(path.Count);
Console.WriteLine(string.Join(" ", path));
}
}
}
C++
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
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pii> vp;
const int INF = 1e9;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m; cin >> n >> m;
vector<vp> adj(n + 1);
for (int i = 0; i < m; i++) {
int a, b, c; cin >> a >> b >> c;
adj[a].push_back({b, c});
}
int start, goal; cin >> start >> goal;
vi dist(n + 1, INF);
vi prev(n + 1, 0);
priority_queue<pii, vp, greater<pii>> pq;
dist[start] = 0;
pq.push({0, start});
while (!pq.empty()) {
auto [d, u] = pq.top(); pq.pop();
if (d > dist[u])
continue;
for (auto [v, w] : adj[u]) {
int nd = dist[u] + w;
if (nd < dist[v]) {
dist[v] = nd;
prev[v] = u;
pq.push({nd, v});
}
}
}
cout << dist[goal] << "\n";
vi path;
for (int v = goal; v != 0; v = prev[v])
path.push_back(v);
reverse(path.begin(), path.end());
cout << path.size() << "\n";
for (int i = 0; i < (int)path.size(); i++)
cout << path[i] << (i + 1 == (int)path.size() ? '\n' : ' ');
return 0;
}