PAT1087. All Roads Lead to Rome

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PAT1087. All Roads Lead to Rome相关的知识,希望对你有一定的参考价值。

PAT1087. All Roads Lead to Rome

题目大意

给定一个图的边权和点权, 求边权最小的路径; 若边权相同, 求点权最大; 若点权相同, 则求平均点权最大.

思路

先通过 Dijkstra 求得最短路径, 需要注意的是: 要保证每次松弛时 u 和 v 不相同, 否则会形成自环, 则从 ROM 开始 BFS 遍历每一条边权相同的路径.

代码

#include <iostream>
#include <cstdio>
#include <vector>
#include <map>
using namespace std;
#define MAXN 300
#define INF 0x7ffffff
int nVertex, nEdge;
map<string, int> s_i;
map<int, string> i_s;
vector<int> prepath[MAXN], temppath, anspath;
int vw[MAXN];
int ew[MAXN][MAXN];
int dis[MAXN];
int isVis[MAXN];
int cntRo = 0;
int ansHapy = 0;
double ansAvg = 0;
void dfs(int loc){
    temppath.push_back(loc);
    if(loc == 0){
        int hapy = 0;
        for(int i = 0; i < temppath.size(); i++)
            hapy += vw[temppath[i]];
        double avgHapy = hapy * 1.0 / (temppath.size() - 1);
        if(hapy > ansHapy){
            ansHapy = hapy;
            ansAvg = avgHapy;
            anspath = temppath;
        }
        else if(hapy == ansHapy && avgHapy > ansAvg){
            ansAvg = avgHapy;
            anspath = temppath;
        }
        cntRo++;
        temppath.pop_back();
        return;
    }
    for(int i = 0; i < prepath[loc].size(); i++){
        dfs(prepath[loc][i]);
    }
    temppath.pop_back();
}
int main(){
    scanf("%d%d", &nVertex, &nEdge);
    string tempStr; cin >> tempStr;
    s_i[tempStr] = 0; i_s[0] = tempStr;
    for(int i = 1; i < nVertex; i++){
        cin >> tempStr;
        s_i[tempStr] = i; i_s[i] = tempStr;
        scanf("%d", &vw[i]);
    }
    for(int i = 0; i < MAXN; i++){
        for(int j = 0; j < MAXN; j++){
            ew[i][j] = (i == j ? 0 : INF);
        }
    }
    for(int i = 0; i < nEdge; i++){
        string a, b; int c;
        cin >> a >> b >> c;
        ew[s_i[a]][s_i[b]] = ew[s_i[b]][s_i[a]] = c;
    }

    for(int i = 0; i < nVertex; i++)
        dis[i] = ew[0][i];
    dis[0] = 0;
    for(int i = 0; i < nVertex; i++){
        int u = -1, minn = INF;
        for(int j = 0; j < nVertex; j++){
            if(!isVis[j] && dis[j] < minn){
                minn = dis[j];
                u = j;
            }
        }
        isVis[u] = 1;
        for(int v = 0; v < nVertex; v++){
            if(u != v)
            {
                if(dis[v] > ew[u][v] + dis[u]){
                    dis[v] = ew[u][v] + dis[u];
                    prepath[v].clear();
                    prepath[v].push_back(u);
                }
                else if(dis[v] == ew[u][v] + dis[u]){
                    prepath[v].push_back(u);
                }
            }
        }
    }
    int rom = s_i["ROM"];
    dfs(rom);
    printf("%d %d %d %d\n", cntRo, dis[rom], ansHapy, (int)ansAvg);
    for(int i = anspath.size() - 1; i != 0; i--){
        cout << i_s[anspath[i]] << "->";
    }
    printf("ROM");
    return 0;
}

以上是关于PAT1087. All Roads Lead to Rome的主要内容,如果未能解决你的问题,请参考以下文章

1087. All Roads Lead to Rome (30)最短路——PAT (Advanced Level) Practise

PAT (Advanced Level) 1087. All Roads Lead to Rome (30)

PAT (Advanced Level) 1087 All Roads Lead to Rome

1087 All Roads Lead to Rome (30 分)难度: 一般 / Dijkstra

1087 All Roads Lead to Rome (30)

(学英语学算法)PAT甲级--All Roads Lead to Rome