1087. All Roads Lead to Rome

Direct Link

#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdio>
#include <cctype>
#include <map>
#include <string>
#include <cstring>
#include <stack>
#include <set>
using namespace std;

const int maxn = 205;
const int INF = 0x3fffffff;
map<string, int> cityID;
vector<pair<string, int>> cityInfo;
vector<pair<int, int>> cityAdjList[maxn]; // adjacent list
vector<int> prevCity[maxn]; // store the prev city of the minimum dist path
int dist[maxn];
bool used[maxn];
int totMinDistPath = 0, endCity;
vector<int> minPathIns;
vector<int> minDistPath[maxn]; // store the minimmum dist paths


void djisktra(int n) {
    // default the city id 0 is the start city
    for (int i = 0; i < n; i++) {
        dist[i] = INF;
        used[i] = false;
    }
    for (int i = 0; i < cityAdjList[0].size(); i++) {
        int curCity = cityAdjList[0][i].first;
        dist[curCity] = cityAdjList[0][i].second;
        prevCity[curCity].push_back(0);
    }
    
    dist[0] = 0;
    used[0] = true;

    for (int i = 1; i < n; i++) {
        // find the minimal distance city from dist[]
        int maxdist = INF;
        int curCity = 0;
        for (int j = 0; j < n; j++) {
            if (!used[j] && dist[j] < maxdist) {
                curCity = j;
                maxdist = dist[j];
            }
        }

        used[curCity] = true;
        // update the dist
        for (int j = 0; j < cityAdjList[curCity].size(); j++) {
            int adjCityID = cityAdjList[curCity][j].first;
            if (!used[adjCityID]) {
                int newdist = dist[curCity] + cityAdjList[curCity][j].second;
                if (newdist <= dist[adjCityID]) {
                    if (newdist < dist[adjCityID]) {
                        prevCity[adjCityID].clear();
                        dist[adjCityID] = newdist;
                    }
                    prevCity[adjCityID].push_back(curCity);
                }
            }
        }
    }
}


void searchPath(int curCity) {
    // reach start city, end up the the recursion
    if (curCity == 0) {
        for (int i = minPathIns.size()-1; i >= 0; i--)
            minDistPath[totMinDistPath].push_back(minPathIns[i]);
        totMinDistPath++;
        return;
    }

    for (int i = 0; i < prevCity[curCity].size(); i++) {
        int prevCityID = prevCity[curCity][i];
        minPathIns.push_back(prevCityID);
        searchPath(prevCityID);
        minPathIns.pop_back();
    }
}

void printInfo() {
    for (int i = 0; i < cityInfo.size(); i++)
        cout << cityInfo[i].first << " : " << i << endl;
    for (int i = 0; i < cityInfo.size(); i++)
        cout << dist[i] << " " ;
    cout << endl;
    cout << "Total Min path : " << totMinDistPath << endl;
    for (int i = 0; i < totMinDistPath; i++) {
        for (int j = 0; j < minDistPath[i].size(); j++) {
            cout << minDistPath[i][j] << " ";
        }
        cout << endl;
    }
}

void printAns() {

    cout << totMinDistPath;
    if (totMinDistPath >= 1) {
        cout << " " << dist[endCity];
        int maxHappy = -1, printPathID = -1;
        double avgHappy = -1;
        for (int i = 0; i < totMinDistPath; i++) {
            int happyVal = 0;
            for (int j = 0; j < minDistPath[i].size(); j++) {
                int curCityID = minDistPath[i][j];
                happyVal += cityInfo[ curCityID ].second;
            }
            if (maxHappy < happyVal) {
                printPathID = i;
                maxHappy = happyVal;
                avgHappy = (double)happyVal / (double)(minDistPath[i].size()-1);
            }
            else if(maxHappy == happyVal) {
                double curAvgHappy = (double)happyVal / (double)(minDistPath[i].size()-1);
                if (curAvgHappy > avgHappy) {
                    printPathID = i;
                    avgHappy = curAvgHappy;
                }
            }
        }

        cout << " " << maxHappy << " " << (int)avgHappy << endl;
        for (int i = 0; i < minDistPath[printPathID].size()-1; i++) {
            int curCityID = minDistPath[printPathID][i];
            cout << cityInfo[curCityID].first << "->";
        }
        cout << "ROM" << endl;
    }   
}

int main() {
    int n, k, cityHappy;
    string startCity, cityName;
    cin >> n >> k >> startCity;
    cityID[startCity] = 0;
    cityInfo.push_back(make_pair(startCity, 0));
    for (int i = 1; i < n; i++) {
        cin >> cityName >> cityHappy;
        cityID[cityName] = i;
        if (cityName == "ROM") endCity = i;
        cityInfo.push_back(make_pair(cityName, cityHappy));
    }
    string cityA, cityB;
    int dis;
    for (int i = 0; i < k; i++) {
        cin >> cityA >> cityB >> dis;
        int aID = cityID[cityA];
        int bID = cityID[cityB];
        cityAdjList[aID].push_back(make_pair(bID, dis));
        cityAdjList[bID].push_back(make_pair(aID, dis));
    }

    djisktra(n);

    totMinDistPath = 0;
    minPathIns.push_back(endCity);
    searchPath(endCity);
    minPathIns.pop_back();

    printAns();

    return 0;
}