首先感谢柳神(她的题解)
根据柳神的思路,我自己写了一遍,分了不同的模块。显得更加条理一些
第一步,建图。
第二步,使用加边权变体迪杰斯特拉算法求解最短路中的花费时间最少的路径。
第三步,使用加点权变体迪杰斯特拉算法求解最快路中的经由结点最少的路径。
第四步,递归方式找出路径。
第五步,根据路径的结果以不同的形式输出。
代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<sstream>
using namespace std;
const int M = 505;
const int INF = INT32_MAX;
int n,e,D[M][M], T[M][M];
int dist[M], timeS[M],distPath[M],timePath[M],distV[M],timeV[M],nodeNum[M];
void initGraph() {
fill(D[0], D[0] + M * M, INF);
fill(T[0], T[0] + M * M, INF);
cin >> n >> e;
int ti, tj, to, tl, tt;
for (int i = 0; i < e; i++) {
cin >> ti >> tj >> to >> tl >> tt;
if (to == 1) {
D[ti][tj] = tl;
T[ti][tj] = tt;
} else {
D[ti][tj] = D[tj][ti] = tl;
T[ti][tj] = T[tj][ti]=tt;
}
}
}
void DijkstraForDist(int start) {
fill(dist, dist + n, INF);
fill(timeS, timeS + n, INF);
for (int i = 1; i < n; i++) {
distPath[i] = i;
}
dist[start] = 0;
timeS[start] = 0;
int k, m;
for (int i = 0; i < n; i++) {
k = -1, m = INF;
for (int j = 0; j < n; j++) {
if (!distV[j] && dist[j] < m) {
m = dist[j];
k = j;
}
}
if (k == -1) {
return;
} else {
distV[k] = true;
}
for (int j = 0; j < n; j++) {
if (!distV[j] && D[k][j] != INF) {
if (dist[k]+D[k][j]<dist[j]) {
dist[j] = dist[k] + D[k][j];
timeS[j] = timeS[k] + T[k][j];
distPath[j] = k;
} else if (dist[k] + D[k][j]== dist[j] && timeS[k] + T[k][j]< timeS[j]) {
timeS[j] = timeS[k] + T[k][j];
distPath[j] = k;
}
}
}
}
}
void DijkstraForTime(int start) {
fill(timeS, timeS + n,INF);
for (int i = 1; i < n; i++) {
timePath[i] = i;
}
timeS[start] = 0;
int k, m;
for (int i = 0; i < n; i++) {
k = -1, m = INF;
for (int j = 0; j < n; j++) {
if (!timeV[j]&&timeS[j]<m) {
m = timeS[j];
k = j;
}
}
if (k==-1) {
return;
} else {
timeV[k] = true;
}
for (int j = 0; j < n; j++) {
if (!timeV[j]&&T[k][j]!=INF) {
if (timeS[k]+ T[k][j]<timeS[j]) {
timeS[j] = timeS[k] + T[k][j];
nodeNum[j] = nodeNum[k] + 1;
timePath[j] = k;
} else if (timeS[k] + T[k][j] == timeS[j] && nodeNum[k] + 1<nodeNum[j]) {
nodeNum[j] = nodeNum[k] + 1;
timePath[j] = k;
}
}
}
}
}
void getPath(int s,int d,bool dist,string &path) {
if (s == d) {
path.append(to_string(d)+" -> ");
return;
}
getPath(s, (dist ? distPath[d] : timePath[d]), dist, path);
path.append(to_string(d)+" -> ");
}
int main() {
//第一步,建图。
initGraph();
int s, d;
cin >> s>>d;
//第二步,使用加边权变体迪杰斯特拉算法求解最短路中的花费时间最少的路径。
DijkstraForDist(s);
//第三步,使用加点权变体迪杰斯特拉算法求解最快路中的经由结点最少的路径。
DijkstraForTime(s);
//第四步,递归方式找出路径。
string distPaths,timePaths;
getPath(s,d,true,distPaths);
getPath(s, d, false, timePaths);
//第五步,根据路径的结果以不同的形式输出。
if (distPaths == timePaths) {
cout << "Distance = " << dist[d] << "; Time = " << timeS[d] << ": " << timePaths.substr(0, timePaths.size() - 4) << endl;
} else {
cout << "Distance = " << dist[d] << ": " << distPaths.substr(0, distPaths.size() - 4) << endl;
cout << "Time = " << timeS[d] << ": " << timePaths.substr(0, timePaths.size() - 4) << endl;
}
return 0;
}