方法一 Dijkstra
#include <stdio.h>
#include <algorithm>
#include <queue>
using namespace std;
const int MAXV = 510;
int Distance[MAXV][MAXV], Cost[MAXV][MAXV];
int N, S, D, INF = 0x3fffffff, cost[MAXV], d[MAXV];
int pre[MAXV];
queue<int> q;
bool vis[MAXV] = {false};
void Dijkstra(int s) {
q.push(s);
d[s] = 0;
cost[s] = 0;
for (int i = 0; i < N; ++i) {
int u = -1, MIN = INF;
for (int j = 0; j < N; ++j) {
if (!vis[j] && d[j] < MIN) {
u = j;
MIN = d[j];
}
}
if (u == -1) return;
vis[u] = true;
for (int v = 0; v < N; ++v) {
if (!vis[v] && Distance[u][v] != INF) {
if (d[u] + Distance[u][v] < d[v]) {
d[v] = d[u] + Distance[u][v];
cost[v] = cost[u] + Cost[u][v];
pre[v] = u;
} else if (d[u] + Distance[u][v] == d[v]) {
if (cost[u] + Cost[u][v] < cost[v]) {
cost[v] = cost[u] + Cost[u][v];
pre[v] = u;
}
}
}
}
}
}
void DFS(int s) {
if (pre[s] != -1)
DFS(pre[s]);
printf("%d ", s);
}
int main() {
fill(d, d + MAXV, INF);
fill(cost, cost + MAXV, INF);
fill(pre, pre + MAXV, -1);
fill(Distance[0], Distance[0] + MAXV * MAXV, INF);
fill(Cost[0], Cost[0] + MAXV * MAXV, 0);
int m;
scanf("%d%d%d%d", &N, &m, &S, &D);
for (int i = 0; i < m; ++i) {
int a, b, d, c;
scanf("%d%d%d%d", &a, &b, &d, &c);
Distance[a][b] = d;
Distance[b][a] = d;
Cost[a][b] = c;
Cost[b][a] = c;
}
Dijkstra(S);
DFS(D);
printf("%d %d\n", d[D], cost[D]);
return 0;
}
方法二 Dijkstra+DFS
#include <stdio.h>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;
const int MAXV = 510;
int G[MAXV][MAXV], W[MAXV][MAXV], d[MAXV], N, S, D, INF = 0x3fffffff;
bool vis[MAXV] = {false};
vector<int> pre[MAXV];
stack<int> path, tempPath;
int cost = INF;
void Dijkstra(int s) {
d[s] = 0;
for (int i = 0; i < N; ++i) {
int u = -1, MIN = INF;
for (int j = 0; j < N; ++j) {
if (!vis[j] && d[j] < MIN) {
u = j;
MIN = d[j];
}
}
if (u == -1) return;
vis[u] = true;
for (int v = 0; v < N; ++v) {
if (!vis[v] && G[u][v] != INF) {
if (d[u] + G[u][v] < d[v]) {
d[v] = d[u] + G[u][v];
pre[v].clear();
pre[v].push_back(u);
} else if (d[u] + G[u][v] == d[v]) {
pre[v].push_back(u);
}
}
}
}
}
void DFS(int v, int localCost) {
tempPath.push(v);
if (v == S) {
if (localCost < cost) {
cost = localCost;
path = tempPath;
}
} else {
for (int i = 0; i < pre[v].size(); ++i) {
DFS(pre[v][i], localCost + W[v][pre[v][i]]);
}
}
tempPath.pop();
}
int main() {
fill(G[0], G[0] + MAXV * MAXV, INF);
fill(d, d + MAXV, INF);
int e;
scanf("%d%d%d%d", &N, &e, &S, &D);
for (int i = 0; i < e; ++i) {
int a, b, dis, cost;
scanf("%d%d%d%d", &a, &b, &dis, &cost);
G[a][b] = G[b][a] = dis;
W[a][b] = W[b][a] = cost;
}
Dijkstra(S);
DFS(D, 0);
while (!path.empty()) {
printf("%d ", path.top());
path.pop();
}
printf("%d %d\n", d[D], cost);
return 0;
}