https://pintia.cn/problem-sets/994805342720868352/problems/994805464397627392
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int SIZE = 1005;
const int INF = 100000000;
struct Node {
int number;
int dis;
Node(int number, int dis) : number(number), dis(dis) {}
};
int Cost[SIZE][SIZE]; //每条道路的消费
int c[SIZE]; //c[i]表示从起始点到i的花费
int N, M, S, D;
vector<Node> adj[SIZE]; //邻接表
bool visit[SIZE] = {false}; //集合
int d[SIZE]; //距离
int pre[SIZE]; //先驱
/*第二种计算cost和最优路径的方法:回溯算法。*/
vector<int> tPre[SIZE];
vector<int> tempPath;
vector<int> path;
int minCost = INF;
void DFS (int v) {
if (v == S) {
int tempCost = 0;
for (int i = tempPath.size() - 1; i > 0; i --) {
int id = tempPath[i], idNext = tempPath[i - 1];
tempCost += Cost[id][idNext];
}
if (tempCost < minCost) {
minCost = tempCost;
path = tempPath;
}
return ;
}
if (v == D) tempPath.push_back(v);
for (int i = 0; i < tPre[v].size(); i ++) {
tempPath.push_back(tPre[v][i]);
DFS(tPre[v][i]);
tempPath.pop_back();
}
}
void Dijk() {
fill(d, d + SIZE, INF);
fill(visit, visit + SIZE, false);
d[S] = 0;
pre[S] = S;
c[S] = 0;
for (int i = 0; i < N; i ++) {
int minI = -1, minDis = INF;
for (int j = 0; j < N; j ++) {
if (visit[j] == false && d[j] < minDis) {
minI = j;
minDis = d[j];
}
}
if (minI == -1) break;
visit[minI] = true;
for (int v = 0; v < adj[minI].size(); v ++) {
int vNumber = adj[minI][v].number;
int vDis = adj[minI][v].dis;
if (visit[vNumber] == false) {
if (d[minI] + vDis < d[vNumber]) {
d[vNumber] = d[minI] + vDis;
pre[vNumber] = minI;
c[vNumber] = c[minI] + Cost[minI][vNumber];
tPre[vNumber].clear();
tPre[vNumber].push_back(minI);
}
else if (d[minI] + vDis == d[vNumber]) {
if (c[minI] + Cost[minI][vNumber] < c[vNumber]) {
c[vNumber] = c[minI] + Cost[minI][vNumber];
pre[vNumber] = minI;
tPre[vNumber].push_back(minI);
}
}
}
}
}
}
int main() {
cin >> N >> M >> S >> D;
int city1, city2, distance, cost;
for (int i = 0; i < M; i ++) {
cin >> city1 >> city2 >> distance >> cost;
Node node1(city1, distance);
Node node2(city2, distance);
adj[city1].push_back(node2);
adj[city2].push_back(node1);
Cost[city1][city2] = cost;
Cost[city2][city1] = cost;
}
Dijk();
vector<int> path;
int tD = D;
while (pre[tD] != tD) {
path.push_back(tD);
tD = pre[tD];
}
DFS(D);
cout << S << " ";
for (int i = path.size() - 1; i >= 0; i --) {
cout << path[i] << " ";
}
cout << d[D] << " " << minCost;
return 0;
}