题目链接
https://pintia.cn/problem-sets/994805342720868352/problems/994805358663417856
题解
题目要求
-
输入
- N:取值范围是[2,500],结点数量,索引为[0,N-1]
- M:正整数,边的数量
- M条边
- 起点和终点
-
输出
-
最短路径
如果最短路径不唯一,输出其中最快的那条路径
-
最快路径
如果最快路径不唯一,输出其中经过结点最少的那条路径
-
解题思路
这道题是先后做两次dijkstra+DFS,即可求解。
解法是dijkstra+DFS的题目还有:
代码
// Problem: PAT Advanced 1111
// URL: https://pintia.cn/problem-sets/994805342720868352/problems/994805358663417856
// Tags: 图 最短路 单源最短路 dijkstra BFS DFS
#include <iostream>
#include <vector>
using namespace std;
int n, m, start, destination;
const int INF = 99999999;
const int MAXN = 500;
bool visited[MAXN];
int dis[MAXN][MAXN];
int timee[MAXN][MAXN];
int minDis[MAXN];
int minTime[MAXN];
vector<int> disPath, timePath, tempPath, disPre[MAXN], timePre[MAXN];
int disPathMinTime = INF, timePathMinNodeCount = INF;
int calcPathTime(vector<int>& vec){
int sum = 0;
for (int i = vec.size() - 1; i >= 1; i--){
sum += timee[vec[i]][vec[i - 1]];
}
return sum;
}
void disDFS(int v)
{
tempPath.push_back(v);
if (v == start){
int pathTime = calcPathTime(tempPath);
if (disPathMinTime > pathTime){
disPath = tempPath;
disPathMinTime = pathTime;
}
tempPath.pop_back();
return;
}
for (int i = 0; i < disPre[v].size(); i++)
disDFS(disPre[v][i]);
tempPath.pop_back();
}
void timeDFS(int v)
{
tempPath.push_back(v);
if (v == start){
if (timePathMinNodeCount > tempPath.size()){
timePath = tempPath;
timePathMinNodeCount = tempPath.size();
}
tempPath.pop_back();
return;
}
for (int i = 0; i < timePre[v].size(); i++)
timeDFS(timePre[v][i]);
tempPath.pop_back();
}
int main()
{
fill(dis[0], dis[0] + MAXN * MAXN, INF);
fill(timee[0], timee[0] + MAXN * MAXN, INF);
fill(minDis, minDis + MAXN, INF);
fill(minTime, minTime + MAXN, INF);
scanf("%d %d", &n, &m);
int v1, v2, oneWay, l, t;
for (int i = 0; i < m; i++){
scanf("%d %d %d %d %d", &v1, &v2, &oneWay, &l, &t);
if (oneWay == 1){
dis[v1][v2] = l;
timee[v1][v2] = t;
}
else if (oneWay == 0){
dis[v1][v2] = dis[v2][v1] = l;
timee[v1][v2] = timee[v2][v1] = t;
}
}
scanf("%d %d", &start, &destination);
minDis[start] = 0;
for (int i = 0; i < n; i++){
int u = -1, tempMin = INF;
for (int j = 0; j < n; j++){
if (!visited[j] && tempMin > minDis[j]){
tempMin = minDis[j];
u = j;
}
}
if (u == -1) break;
visited[u] = true;
for (int v = 0; v <n; v++){
if (!visited[v] && dis[u][v] != INF){
if (minDis[v] > minDis[u] + dis[u][v]){
minDis[v] = minDis[u] + dis[u][v];
disPre[v].clear();
disPre[v].push_back(u);
}
else if (minDis[v] == minDis[u] + dis[u][v]){
disPre[v].push_back(u);
}
}
}
}
disDFS(destination);
fill(visited, visited + MAXN, false);
minTime[start] = 0;
for (int i = 0; i < n; i++){
int u = -1, tempMin = INF;
for (int j = 0; j < n; j++){
if (!visited[j] && tempMin > minTime[j]){
u = j;
tempMin = minTime[j];
}
}
if (u == -1) break;
visited[u] = true;
for (int v = 0; v < n; v++){
if (!visited[v] && timee[u][v] != INF){
if (minTime[v] > minTime[u] + timee[u][v]){
minTime[v] = minTime[u] + timee[u][v];
timePre[v].clear();
timePre[v].push_back(u);
}
else if (minTime[v] == minTime[u] + timee[u][v]){
timePre[v].push_back(u);
}
}
}
}
tempPath.clear();
timeDFS(destination);
bool isIdentical = true;
if (disPath.size() == timePath.size()){
for (int i = 0; i < disPath.size(); i++){
if (disPath[i] != timePath[i]){
isIdentical = false;
break;
}
}
}
else{
isIdentical = false;
}
if (isIdentical){
printf("Distance = %d; Time = %d: %d", minDis[destination], minTime[destination], start);
for (int i = disPath.size() - 2; i >= 0; i--){
printf(" -> %d", disPath[i]);
}
}
else{
printf("Distance = %d: %d", minDis[destination], start);
for (int i = disPath.size() - 2; i >= 0; i--){
printf(" -> %d", disPath[i]);
}
printf("
Time = %d: %d", minTime[destination], start);
for (int i = timePath.size() - 2; i >= 0; i--){
printf(" -> %d", timePath[i]);
}
}
return 0;
}
作者:@臭咸鱼
转载请注明出处:https://www.cnblogs.com/chouxianyu/
欢迎讨论和交流!