• PAT甲级1087All Roads Lead to Rome


    题目链接

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

    题解

    题目要求

    找到成本最低、快乐值总和最高的路径。优先找成本最低的,然后再找快乐值最高的,然后再找平均快乐值最高的。

    • 输入
      • N:正整数,[2,200],城市的数量
      • K:正整数,路径的数量
      • 起始城市的名称
      • N-1个城市的名字及其快乐值
      • K条路径
    • 输出
      • 成本最低的路径的数量
      • 成本
      • 快乐值总和
      • 平均快乐值(只输出整数部分)
      • 路径

    解题思路

    这是一道dijkstra+DFS的题,和PAT甲级1018Public Bike Management很类似,所以详细思路不再说明。

    • 用两个map将城市的名字和索引相互对应
    • 用dijkstra算法求出起始城市到所有城市的最短距离,并记录每个城市的前驱城市
    • 使用DFS求出路径(并计算、比较快乐值总和与平均值)

    代码

    // Problem: PAT Advanced 1087
    // URL: https://pintia.cn/problem-sets/994805342720868352/problems/994805379664297984
    // Tags: 图 最短路 单源最短路 dijkstra BFS DFS
    
    #include <iostream>
    #include <map>
    #include <vector>
    #include <string>
    using namespace std;
    
    int n, k;
    string startCity;
    
    map<string, int> sti;
    map<int, string> its;
    
    const int INF = 9999999;
    const int MAXN = 201;
    int dis[MAXN][MAXN];
    int minDis[MAXN];
    bool visited[MAXN];
    int happiness[MAXN];
    vector<int> pre[MAXN];
    vector<int> path;
    vector<int> tempPath;
    int ansHappinessSum = -INF, ansPathNum = 0;
    double ansHappinessAve = -INF;
    
    void dfs(int v){
        tempPath.push_back(v);
    
        if (v == 1){ // 到达起点
            int happinessSum = 0;
            for (auto iter = tempPath.begin(); iter != tempPath.end(); iter++)
                happinessSum += happiness[*iter];
            double happinessAve = happinessSum * 1.0 / (tempPath.size() - 1);
            if (ansHappinessSum < happinessSum){
                path = tempPath;
                ansHappinessSum = happinessSum;
                ansHappinessAve = happinessAve;
            }
            else if (ansHappinessSum == happinessSum && ansHappinessAve < happinessAve){
                path = tempPath;
                ansHappinessAve = happinessAve;
            }
            ansPathNum++;
            tempPath.pop_back();
            return ;
        }
    
        for (int i = 0; i < pre[v].size(); i++)
            dfs(pre[v][i]);
    
        tempPath.pop_back();
    }
    
    int main()
    {
        fill(dis[0], dis[0] + MAXN * MAXN, INF);
        fill(minDis, minDis + MAXN, INF);
    
        scanf("%d %d", &n, &k);
        cin >> startCity;
        sti[startCity] = 1;
        its[1] = startCity;
    
        string s;
        int h;
        for (int i = 2; i <= n; i++){
            cin >> s;
            sti[s] = i;
            its[i] = s;
            scanf("%d", &h);
            happiness[i] = h;
        }
        
        string t;
        for (int i = 0; i < k; i++){
            cin >> s >> t;
            scanf("%d", &dis[sti[s]][sti[t]]);
            dis[sti[t]][sti[s]] = dis[sti[s]][sti[t]];
        }
    
        minDis[1] = 0;
        for (int i = 1; i <= n; i++){
            int tempMin = INF, u = -1;
            for (int j = 1; j <= n; j++){
                if (!visited[j] && tempMin > minDis[j]){
                    tempMin = minDis[j];
                    u = j;
                }
            }
            if (u == -1) break;
            visited[u] = true;
    
            for (int v = 1; 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];
                        pre[v].clear();
                        pre[v].push_back(u);
                    }
                    else if (minDis[v] == minDis[u] + dis[u][v]){
                        pre[v].push_back(u);
                    }
                }
            }
        }
    
        dfs(sti["ROM"]);
    
        printf("%d %d %d %d
    %s", ansPathNum, minDis[sti["ROM"]], ansHappinessSum, int(ansHappinessAve), startCity.c_str());
        for (int i = path.size() - 2; i >= 0; i--)
            printf("->%s", its[path[i]].c_str());
    
        return 0;
    }
    

    作者:@臭咸鱼

    转载请注明出处:https://www.cnblogs.com/chouxianyu/

    欢迎讨论和交流!


  • 相关阅读:
    spl_autoload_register()和__autoload()区别
    编程语言相关科目
    类继承和重写的区别
    心理扭曲和心理变态含义分别是什么?
    java中的静态方法
    《深入理解JavaScript》—— JSON
    《深入理解JavaScript》—— Date
    《深入理解JavaScript》—— 正则表达式
    《深入理解JavaScript》—— 数组
    《深入理解JavaScript》—— 对象与继承(第2层)
  • 原文地址:https://www.cnblogs.com/chouxianyu/p/13709220.html
Copyright © 2020-2023  润新知