题目地址:
https://www.acwing.com/problem/content/1509/
给定一张地图,包含 N N N个城市, M M M条高速公路。城市之间都能相互连通。每条高速公路的长度和走该条公路的花费都是已知的,高速公路都是双向的。现在要从地图中的某个城市前往另一个城市。请你确定最短路径,当最短路径不唯一时,请你选取花费最小的路径(保证唯一)。
输入格式:
第一行包含四个整数
N
,
M
,
S
,
D
N,M,S,D
N,M,S,D,分别表示城市数量,公路数量,起点城市编号,终点城市编号。城市编号从
0
0
0到
N
−
1
N−1
N−1。
接下来
M
M
M行,每行包含四个整数
a
,
b
,
c
,
d
a,b,c,d
a,b,c,d,表示城市
a
a
a和城市
b
b
b之间存在一条公路,长度为
c
c
c,花费为
d
d
d。
输出格式:
共一行,首先输出从起点城市到终点城市的最短路径(花费最少的)经过的所有城市,然后输出最短路径的距离以及最小的花费。
数据范围:
1
≤
N
≤
500
1≤N≤500
1≤N≤500
1
≤
M
≤
600
1≤M≤600
1≤M≤600
1
≤
c
,
d
≤
500
1≤c,d≤500
1≤c,d≤500
Dijkstra算法。为了输出路径,可以从终点到起点搜最短路。代码如下:
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
using PI = pair<pair<int, int>, int>;
const int N = 510, M = 610;
int n, m, st, ed;
int h[N], e[M << 1], ne[M << 1], c[M << 1], d[M << 1], idx;
bool vis[N];
int dist_glob[N], cost_glob[N];
int pre[N];
#define add(a, b, cost, dist) \
e[idx] = b, ne[idx] = h[a], c[idx] = cost, d[idx] = dist, h[a] = idx++
pair<int, int> dijkstra() {
memset(dist_glob, 0x3f, sizeof dist_glob);
memset(cost_glob, 0x3f, sizeof cost_glob);
priority_queue<PI, vector<PI>, greater<>> heap;
heap.push({{0, 0}, ed});
while (heap.size()) {
auto t = heap.top();
heap.pop();
#define x first
#define y second
int dist = t.x.x, cost = t.x.y, u = t.y;
if (u == st) return {dist, cost};
if (vis[u]) continue;
vis[u] = true;
dist_glob[u] = dist;
cost_glob[u] = cost;
for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i], cost_v = c[i], dist_v = d[i];
if (!vis[v] &&
(dist_glob[v] > dist + dist_v ||
dist_glob[v] == dist + dist_v && cost_glob[v] > cost + cost_v)) {
dist_glob[v] = dist + dist_v;
cost_glob[v] = cost + cost_v;
pre[v] = u;
heap.push({{dist_glob[v], cost + cost_v}, v});
}
}
}
return {-1, -1};
}
int main() {
memset(h, -1, sizeof h);
scanf("%d%d%d%d", &n, &m, &st, &ed);
for (int i = 1; i <= m; i++) {
int a, b, cost, dist;
scanf("%d%d%d%d", &a, &b, &cost, &dist);
add(a, b, dist, cost), add(b, a, dist, cost);
}
auto [a, b] = dijkstra();
int x = st;
while (x != ed) {
printf("%d ", x);
x = pre[x];
}
printf("%d %d %d\n", ed, dist_glob[st], cost_glob[st]);
}
时间复杂度 O ( m log n ) O(m\log n) O(mlogn),空间 O ( n ) O(n) O(n)。