题目
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
建立城市名到编号的map,用于构建地图,从而搜索。
建立编号到城市名的表,用于根据搜索到的路线输出。
将出发地的id设置为0,记录ROM的id,剩下的就是地图搜索了。
dijkstra,dfs搜索路线数,同时记录每条路线的happiness和长度,
刷新最短路线、最短路线的路线数、最短路线happiness总和等信息。
代码:
#include <iostream>
#include <vector>
#include <string>
#include <map>
using namespace std;
const int MAX=0x3fffffff;
struct way_point //路线探测结构
{
int city; //到达的城市
int cost; //此时的开销
int happy_sum; //到达某个位置时的总快乐值
vector<int> road; //经过的城市,这个属性可以不加,单独设置一个路线存储,节省空间
};
int main()
{
map<string,int> index; //城市名对应的id
vector<string> id_to_name; //id对应的城市名
int **ways; //地图路线
int *happiness; //各个城市的快乐值
int n,k,id_rom,tempi; //n,k,罗马的id,临时数据
string name,name1; //临时城市名称
int i,j;
cin>>n>>k>>name; //输入信息
ways=new int*[n+1]; //初始化
for(i=0;i<=n;i++)
{
ways[i]=new int[n+1];
for(j=0;j<=n;j++)
ways[i][j]=MAX;
}
happiness=new int[n+1];
for(i=0;i<=n;i++)
happiness[i]=0;
index[name]=1; //处理出发地
id_to_name.push_back(name);
id_to_name.push_back(name);
happiness[0]=0;
happiness[1]=0;
for(i=2;i<=n;i++) //输入快乐值
{
cin>>name>>tempi;
index[name]=i;
id_to_name.push_back(name);
happiness[i]=tempi;
if(name=="ROM")
id_rom=i;
}
for(i=0;i<k;i++) //输出城市
{
cin>>name>>name1>>tempi;
ways[index[name]][index[name1]]=tempi;
ways[index[name1]][index[name]]=tempi;
}
int *dis=new int[n+1]; //对应id城市的距离
int *flag=new int[n+1]; //相应城市是否用于松弛
for(i=0;i<=n;i++) //初始化
{
flag[i]=0;
dis[i]=MAX;
}
dis[1]=0;
int use=1; //本轮松弛点
int next,min_dis; //次轮松弛点,松弛点的距离
while(use!=0) //dijkstra
{
flag[use]=1;
next=0;
min_dis=MAX;
for(i=1;i<=n;i++)
{
if(dis[use]+ways[use][i]<dis[i])
dis[i]=dis[use]+ways[use][i];
if(dis[i]<min_dis&&flag[i]==0)
{
next=i;
min_dis=dis[i];
}
}
use=next;
}
vector<way_point> way_test; //路线探测,dfs
way_point wt1,wt2,wtd; //临时点1,临时点2,保存最佳路线
int num_ways=0; //路线数
wt1.city=id_rom; //从罗马开始寻找起点
wt1.cost=0;
wt1.happy_sum=happiness[id_rom];
wt1.road.push_back(id_rom);
way_test.push_back(wt1);
wtd.cost=MAX;
while(!way_test.empty()) //dfs
{
wt1=way_test.back();
way_test.pop_back();
if(wt1.city==1) //是起点
{
if(wt1.cost<wtd.cost)
{
wtd=wt1;
num_ways=1;
}
else if(wt1.cost==wtd.cost)
{
num_ways++;
if(wt1.happy_sum>wtd.happy_sum||
(wt1.happy_sum==wtd.happy_sum)&&wt1.road.size()<wtd.road.size())
wtd=wt1;
}
}
else //不是起点
{
for(i=1;i<=n;i++)
{
if(ways[i][wt1.city]!=MAX&&dis[i]+ways[i][wt1.city]==dis[wt1.city])
{
wt2.city=i;
wt2.cost=wt1.cost+ways[i][wt1.city];
wt2.happy_sum=wt1.happy_sum+happiness[i];
wt2.road=wt1.road;
wt2.road.push_back(i);
way_test.push_back(wt2);
}
}
}
}
cout<<num_ways<<" "<<wtd.cost<<" "<<wtd.happy_sum<<" "<<wtd.happy_sum/(wtd.road.size()-1)<<endl; //输出数据
for(i=wtd.road.size()-1;i>0;i--)
cout<<id_to_name[wtd.road[i]]<<"->";
if(i>=0)
cout<<id_to_name[wtd.road[i]];
return 0;
}