PAT 1003 Emergency

原题目:

As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road between any pair of cities are marked on the map. When there is an emergency call to you from some other city, your job is to lead your men to the place as quickly as possible, and at the mean time, call up as many hands on the way as possible.

Input Specification:
Each input file contains one test case. For each test case, the first line contains 4 positive integers: N (≤500) - the number of cities (and the cities are numbered from 0 to N−1), M - the number of roads, C​1 and C2 - the cities that you are currently in and that you must save, respectively. The next line contains N integers, where the i-th integer is the number of rescue teams in the i-th city. Then M lines follow, each describes a road with three integers c1, c2 and L, which are the pair of cities connected by a road and the length of that road, respectively. It is guaranteed that there exists at least one path from C​1 to C​2.

Output Specification:
For each test case, print in one line two numbers: the number of different shortest paths between C​1 and C2, and the maximum amount of rescue teams you can possibly gather. All the numbers in a line must be separated by exactly one space, and there is no extra space allowed at the end of a line.
这里说要输出两个数,第一是,C1到C2之间最短路径的线路个数;第二个是,可集合的救援队最大数量;这里不得不说第二个输出的表述实在过于模棱两可,通过测试可知,应该是,最短线路中,单个线路可集合救援队的最大数量;

Sample Input:

5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1

Sample Output:
2 4





version 2:

#include "iostream"
#include <iomanip>
#include <list>
#include <climits>
using namespace std;



int getThisRoundStart(int * shortestLength, bool *settled , int vertexCount) {

    int unsettleShortestIndex = -1;
    int unsettleShortestLength = INT_MAX;
    for (int i = 0; i < vertexCount; ++i) {
        if (!settled[i]){
            //没有settle
            if(shortestLength[i] < unsettleShortestLength){
                //距离最短
                unsettleShortestIndex = i;
                unsettleShortestLength = shortestLength[i];
            }
        }
    }
    return unsettleShortestIndex;

}

int main(){
    //城市数量
    int cityNum;
    //线路数量
    int lineNum;
    //起始城市
    int s;
    //目的地城市
    int t;
    //lineList 每个line 包含三个元素 1from 2to 3distance
    list<int*> lineList;
    /**
     * 输入城市数量,线路数量
     */
    cin >> cityNum >> lineNum >> s >> t;

    //顶点是否settle数组
    bool  *settled = new bool[cityNum];
    //顶点到起始点的最短距离
    int  *shortestLength = new int[cityNum];
    //顶点和起点多个最短线路的前一个点的集合(因为最短距离可能有多个线路)
    list<int> *preList = new list<int>[cityNum];
    //每个城市的救援队数量
    int *cityRescue = new int[cityNum];
    /**
     * 输入每个城市救援队数量
     */
    for (int i = 0; i < cityNum; ++i) {
        cin >> cityRescue[i];
        preList[i] = {};
        settled[i] = false;
        shortestLength[i] = INT_MAX;
    }
    /**
     * 输入线路配置(双向)
     */
    for (int j = 0; j < lineNum; ++j) {
        int lineFrom;
        int lineTo;
        int lineDistance;
        cin >> lineFrom >> lineTo >> lineDistance;
        int * lineArr = new int[3]{lineFrom, lineTo, lineDistance};
        int * lineArrReverse = new int[3]{lineTo, lineFrom, lineDistance};
        lineList.push_back(lineArr);
        lineList.push_back(lineArrReverse);

    }


    //每个顶点对于到s的最短线路的数量
    int pathCount[cityNum] = {0};
    //每个顶点对应到s的最大救援队数量(最短的线路中,取救援队最多的)
    int cityRescueSum[cityNum] = {0};


    //初始化起点
    shortestLength[s] = 0;
    pathCount[s] = 1;
    cityRescueSum[s] = cityRescue[s];

    while (true){
        int thisRoundStart = getThisRoundStart(shortestLength, settled, cityNum);
        if(thisRoundStart == -1){
            break;
        }
        //起点先settle
        settled[thisRoundStart] = true;

        //开始线路轮询比较
        list<int*>::iterator it ;
        for(it = lineList.begin();it!= lineList.end();it++){

            int thisFrom = (*it)[0];
            int thisTo = (*it)[1];
            int thisDistance = (*it)[2];
            if(thisRoundStart == thisFrom && !settled[thisTo]){
                int newLength = thisDistance + shortestLength[thisFrom];
                if (newLength < shortestLength[thisTo]){
                    preList[thisTo] = {thisFrom};
                    shortestLength[thisTo] = newLength;
                    pathCount[thisTo] = pathCount[thisFrom];
                    cityRescueSum[thisTo] = cityRescueSum[thisFrom] + cityRescue[thisTo];
                } else if (newLength == shortestLength[thisTo]) {
                    preList[thisTo].push_front(thisFrom);
                    pathCount[thisTo] = pathCount[thisTo] + pathCount[thisFrom];
                    if (cityRescueSum[thisTo] < cityRescueSum[thisFrom] + cityRescue[thisTo]){
                        cityRescueSum[thisTo] = cityRescueSum[thisFrom] + cityRescue[thisTo];
                    }
                }
            }
        }

    }


    if (settled[t]){
        cout << pathCount[t] << " " << cityRescueSum[t];
    }
}

version 1:


#include "iostream"
#include <iomanip>
#include <list>
#include <map>
using namespace std;

class BestRoute{
public:
    list<list<int>>  routeList;
    int distance;
    bool settled = false;
};


int getThisRoundStart(map<int, BestRoute> * reusltMap, int to) {
    map<int, BestRoute>::iterator it = (*reusltMap).begin();
    int lowestToSite = -1;
    int lowestDistance = INT8_MAX;
    for (; it!= (*reusltMap).end() ; ++it) {
        if (! it->second.settled){
            if (it->second.distance < lowestDistance){
                lowestToSite = it->first;
                lowestDistance = it->second.distance;
            }
        }
    }
    if (lowestToSite != -1){
        (*reusltMap).find(lowestToSite)->second.settled = true;
    }
    if(lowestToSite == to){
        return -1;
    }
    return lowestToSite;
}



int main(){
    int cityNum;
    int lineNum;
    int from;
    int to;
    int * cityRescue;
    list<int*> lineList;
    map<int, BestRoute> bestRouteMap;
    cin >> cityNum >> lineNum >> from >> to;
    cityRescue = new int[cityNum];
    for (int i = 0; i < cityNum; ++i) {
        cin >> cityRescue[i];
    }
    for (int j = 0; j < lineNum; ++j) {
        int lineFrom;
        int lineTo;
        int lineDistance;
        cin >> lineFrom >> lineTo >> lineDistance;
        int * lineArr = new int[3]{lineFrom, lineTo, lineDistance};
        lineList.push_back(lineArr);
    }

    BestRoute *firstRoute = new BestRoute();
    firstRoute->distance=0;
    firstRoute->settled = false;
    list<int> fr;
    fr.push_back(from);
    list<list<int>> frr;
    frr.push_back(fr);
    firstRoute->routeList = frr;

    bestRouteMap[from] = *firstRoute;


    while (true){
        int thisRoundStart = getThisRoundStart(&bestRouteMap, to);
        if(thisRoundStart == -1){
            break;
        }
        if(lineList.size() == 0){
            break;
        }

        BestRoute routeBefore = bestRouteMap.find(thisRoundStart)->second;
        list<int*>::iterator it ;
        for(it = lineList.begin();it!= lineList.end();){

            int thisFrom = (*it)[0];
            int thisTo = (*it)[1];
            int thisDistance = (*it)[2];
            if(thisRoundStart == thisFrom || thisRoundStart == thisTo){
                if (thisRoundStart == thisTo){
                    thisTo = thisFrom;
                }
                if(bestRouteMap.find(thisTo) != bestRouteMap.end()){
                    BestRoute & existRoute = bestRouteMap.find(thisTo)->second;
                    //判断和存在的路由相比,那个更短
                    if (existRoute.distance > (thisDistance + routeBefore.distance)){
                        BestRoute *br = new BestRoute();
                        br->distance = routeBefore.distance + thisDistance;
                        br->routeList = routeBefore.routeList;
                        list<list<int>>::iterator it2;
                        for(it2 = br->routeList.begin(); br->routeList.end() != it2; it2++){
                            it2->push_back(thisTo);
                        }
                        bestRouteMap[thisTo] = *br;
                    } else if(existRoute.distance == (thisDistance + routeBefore.distance)){
                        list<int> newRoute;
                        list<list<int>> newRouteList = routeBefore.routeList;
                        list<list<int>>::iterator iterate;
                        for(iterate = newRouteList.begin(); iterate != newRouteList.end(); iterate++){
                            iterate->push_back(thisTo);
                            existRoute.routeList.push_back(*iterate);
                        }

                    }

                    
                }else{
                    BestRoute *br = new BestRoute();
                    br->distance = routeBefore.distance + thisDistance;
                    br->routeList = routeBefore.routeList;
                    list<list<int>>::iterator it2;
                    for(it2 = br->routeList.begin(); br->routeList.end() != it2; it2++){
                        it2->push_back(thisTo);
                    }
                    bestRouteMap[thisTo] = *br;
                }

                it = lineList.erase(it);
            } else {
                it++;
            }
        }

    }


    map<int, BestRoute>::iterator resultIt = bestRouteMap.find(to);



    if(resultIt != bestRouteMap.end()){
        BestRoute br = resultIt->second;
        int sumRescue = 0;

        list<list<int>>::iterator itt;
        for(itt = br.routeList.begin(); itt != br.routeList.end(); itt++){
            int thisSumRes = 0;
            list<int> insideList = *itt;
            list<int>::iterator itttt;
            for(itttt = insideList.begin(); itttt != insideList.end(); itttt++){
                int site = *itttt;
                thisSumRes += cityRescue[site];
            }
            if(sumRescue < thisSumRes){
                sumRescue = thisSumRes;
            }
        }
        cout << br.routeList.size() << " " << sumRescue;
    }else {

        cout << "0 "<< cityRescue[to];

    }




}

posted on 2020-09-04 16:40  mindSucker  阅读(105)  评论(0编辑  收藏  举报