PAT甲级1111Online Map

题目链接

https://pintia.cn/problem-sets/994805342720868352/problems/994805358663417856

题解

题目要求

  • 输入

    • N:取值范围是[2,500],结点数量,索引为[0,N-1]
    • M:正整数,边的数量
    • M条边
    • 起点和终点
  • 输出

    • 最短路径

      如果最短路径不唯一,输出其中最快的那条路径

    • 最快路径

      如果最快路径不唯一,输出其中经过结点最少的那条路径

解题思路

这道题是先后做两次dijkstra+DFS,即可求解。

解法是dijkstra+DFS的题目还有:

  1. PAT甲级1087All Roads Lead to Rome
  2. PAT甲级1030Travel Plan
  3. PAT甲级1018Public Bike Management

代码

// 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("\nTime = %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/

欢迎讨论和交流!


posted @ 2020-09-24 16:04  臭咸鱼  阅读(120)  评论(0)    收藏  举报