天天看點

pat 1087. All Roads Lead to Rome (30) pat 1087. All Roads Lead to Rome (30)

pat 1087. All Roads Lead to Rome (30)

時間限制 200 ms

記憶體限制 32000 kB

代碼長度限制 16000 B

判題程式 Standard 作者 CHEN, Yue

Indeed there are many different tourist routes from our city to Rome. You are supposed to find your clients the route with the least cost while gaining the most happiness.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive integers N (2<=N<=200), the number of cities, and K, the total number of routes between pairs of cities; followed by the name of the starting city. The next N-1 lines each gives the name of a city and an integer that represents the happiness one can gain from that city, except the starting city. Then K lines follow, each describes a route between two cities in the format "City1 City2 Cost". Here the name of a city is a string of 3 capital English letters, and the destination is always ROM which represents Rome.

Output Specification:

For each test case, we are supposed to find the route with the least cost. If such a route is not unique, the one with the maximum happiness will be recommended. If such a route is still not unique, then we output the one with the maximum average happiness -- it is guaranteed by the judge that such a solution exists and is unique.

Hence in the first line of output, you must print 4 numbers: the number of different routes with the least cost, the cost, the happiness, and the average happiness (take the integer part only) of the recommended route. Then in the next line, you are supposed to print the route in the format "City1->City2->...->ROM".

Sample Input:

6 7 HZH
ROM 100
PKN 40
GDN 55
PRS 95
BLN 80
ROM GDN 1
BLN ROM 1
HZH PKN 1
PRS ROM 2
BLN HZH 2
PKN GDN 1
HZH PRS 1
      

Sample Output:

3 3 195 97
HZH->PRS->ROM
      

今天又進行了一次pat甲級考試,對于這次pat考試,我隻能說,悔恨不已。我已經練習了很多題目,前面的題目,我都很容易就過了。雖然不是很快,我前三道題目,隻有第二道題目的第一次編譯沒通過,因為當時換電腦,怕丢失,就急急慢慢送出了一次。其實我那個流程全部都是對的。可是第四道題目來了,傳說中最難的題目,我感覺有點不知所措,我看了題目之後,想出了思路,然後整個流程都是對的。字元串和數字互換,求最短路徑,然後求最短路徑當中最優的路徑。可惜我看錯了題目,其中有一道題目需要輸出最短路徑的條數,我一直看不懂 the number of different routes with the least cost 是啥意思,第一次我了解了,是有多少條路徑,可是我做的時候就忘記了,了解成了最優解當中,有多少個城市,唉。最開始都把這個忽視了,以後對于輸入輸出一定要小心的看。

總的來說,這次我就是在審題上出錯了,以後對于輸入輸出一定要小心看清楚,編寫代碼。雖然pat考察的點比較固定,但是每次輸入輸出都是有變化的。是以就要小心。這次我考了85分,應該來說對比上次不到四十分,算比較好了。可是還不甘心,感覺人應該知足了。哈哈!

下面上代碼:

經典的求最短路徑當中,滿足條件的最短路徑。我一半用dijkstra+dfs+剪枝,代碼會比較長。有人直接用dfs做也可以,一邊搜素,一邊修改。

#include <iostream>
#include <stdio.h>
#include <string>
#include <map>
#include <vector>

using namespace std;
#define MAX 66666666
#define SIZE 203
// output: number of routes,lowest cost, happiness,avgHap
vector<int> resPath;
int routeSum=0,shortest = MAX,resHap=0,avgHap = 0;
map<string,int> hapiness1;
map<int,string> hapiness2;
map<int,int> hapSet;
int graph[SIZE][SIZE];
int dij[SIZE];
int visit[SIZE];
int n,k;
void dfs(int start,int end,vector<int> &path,int hapSum,int pathSum);
void dijkstra(int s);

int main()
{
    int i,j,index1,tmp1,tmp2,tmp3;
    int dest = 0;
    string city1,city2,city3,city4;
    cin>>n>>k>>city1;
    index1= 0;
    hapiness1[city1] = index1;
    hapiness2[index1] = city1;
    hapSet[index1] = 0;
    for(i=1;i<n;i++)
    {
        cin>>city2>>tmp1;
        if(city2.compare("ROM")==0)
        {
            dest = i;
        }
        hapiness1[city2] = i;
        hapiness2[i] = city2;
        hapSet[i] = tmp1;
    }
    for(i=0;i<n;i++)
    {
        dij[i] = MAX;
        for(j=0;j<n;j++)
        {
            graph[i][j] = MAX;
        }
    }
    for(i=0;i<k;i++)
    {
        cin>>city2>>city3>>tmp1;
        tmp2 = hapiness1[city2];
        tmp3 = hapiness1[city3];
        if(tmp1<graph[tmp2][tmp3])
        {
            graph[tmp2][tmp3] = tmp1;
            graph[tmp3][tmp2] = tmp1;
        }
    }
    
    dijkstra(0);
    for(i=0;i<n;i++)
    {
        visit[i] = 0;
    }
    shortest = dij[dest];
    vector<int> myPath(1,0);
    visit[0] = 1;
    dfs(0,dest,myPath,0,0);
    printf("%d %d %d %d\n",routeSum,shortest,resHap,avgHap);
    cout<<city1;
    for(i=1;i<resPath.size();i++)
    {
        cout<<"->"<<hapiness2[resPath[i]];
    }
    cout<<endl;
    return 0;
}

void dfs(int start,int end,vector<int> &path,int hapSum,int pathSum)
{
    int i,j;
    if(pathSum>shortest)
    {
        return ;
    }
    if(start==end)
    {
        if(pathSum>shortest)
        {
            return ;
        }
        routeSum ++;
        if(hapSum<resHap)
        {
            return ;
        }
        int ta = hapSum/(path.size()-1);
        if(ta>avgHap)
        {
            resPath = path;
            avgHap = ta;
            resHap = hapSum;
        }
        return ;
    }
    for(i=0;i<n;i++)
    {
        if(!visit[i] && graph[start][i]!=MAX)
        {
            path.push_back(i);
            visit[i] = 1;
            dfs(i,end,path,hapSum + hapSet[i],pathSum+graph[start][i]);
            path.pop_back();
            visit[i] = 0;
        }
    }
}
//6:52 ->6:58
void dijkstra(int s)
{
    int i,j,tmp,so;
    for(i=0;i<n;i++)
    {
        dij[i] = graph[s][i];
        visit[i] = 0;
    }
    dij[s] = 0;
    visit[s] = 1;
    
    for(i=1;i<n;i++)
    {
        tmp = MAX;
        so = s;
        for(j=0;j<n;j++)
        {
            if(!visit[j] && dij[j]<tmp)
            {
                tmp = dij[j];
                so = j;
            }
        }
        visit[so] = 1;
        for(j=0;j<n;j++)
        {
            if(!visit[j] && dij[so]+graph[so][j]<dij[j])
            {
                dij[j] = dij[so]+graph[so][j];
            }
        }
    }
    
}
           

繼續閱讀