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), 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 recommanded. 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 recommanded 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

题意:

题目大体上是一个求最短路的问题,只不过又在此基础上增加了一些其他的内容,比如说:找出最短路的条数,以及路途过程中happinese的最大值和average happinese的最大值问题。

思路:

最短路径涉及到图论,所以就要表示出图,这里我用的是连接矩阵来表示图,所以先用map将城市的名字改成数字,最后输出的时候再改回来。然后就是用Dijkstra来求最短路了。

Code:

#include<iostream>
#include<map>
#include<string>
#include<vector>
#include<stack> using namespace std;
const int Inf = 0x7fffffff; int findMinDist(vector<int> &dist, vector<bool> &collected) {
int ret = Inf, j = -1;
int len = dist.size();
for (int i = 1; i < len; ++i) {
if (!collected[i] && ret > dist[i]) {
ret = dist[i];
j = i;
}
}
return j;
} int main() {
int n, k;
string start; cin >> n >> k >> start; map<string, int> EnToNum;
map<int, string> NumToEn;
EnToNum[start] = 0;
NumToEn[0] = start;
vector<int> happiness(n);
string name;
int value;
for (int i = 1; i < n; ++i) {
cin >> name >> value;
EnToNum[name] = i;
NumToEn[i] = name;
happiness[i] = value;
} vector<vector<int> > martix(n, vector<int>(n, -1));
vector<bool> collected(n, false);
vector<int> path(n, -1);
string name1, name2;
int num1, num2, cost;
for (int i = 0; i < k; ++i) {
cin >> name1 >> name2 >> cost;
num1 = EnToNum[name1];
num2 = EnToNum[name2];
martix[num1][num2] = cost;
martix[num2][num1] = cost;
} vector<int> dist(n, Inf);
dist[0] = 0;
collected[0] = true;
for (int i = 1; i < n; ++i) {
if (martix[0][i] > 0) {
dist[i] = martix[0][i];
path[i] = 0;
}
} int end = EnToNum["ROM"];
vector<pair<int, int> > backtrack;
// Dijkstra算法
while (1) {
int minVertex = findMinDist(dist, collected);
if (minVertex == -1) break;
collected[minVertex] = true;
for (int i = 0; i < n; ++i) {
if (martix[minVertex][i] > 0 && !collected[i]) {
if (dist[minVertex] + martix[minVertex][i] <= dist[i]) {
dist[i] = dist[minVertex] + martix[minVertex][i];
path[i] = minVertex;
if (i == end) {
backtrack.push_back({dist[i], minVertex});
}
}
}
}
} int count = 0;
vector<int> Vbacktrack;
for (int i = 0; i < backtrack.size(); ++i) {
if (backtrack[i].first == dist[end]) {
count++;
Vbacktrack.push_back(backtrack[i].second);
}
} int maxHappinese = -1, aveHappinese = -1;
int maxHappVertex;
for (int i = 0; i < Vbacktrack.size(); ++i) {
int begin = Vbacktrack[i], temp = happiness[end], numOfVertex = 1;
while (path[begin] != -1) {
temp += happiness[begin];
numOfVertex++;
begin = path[begin];
}
if (temp > maxHappinese) {
maxHappinese = temp;
aveHappinese = temp / numOfVertex;
maxHappVertex = Vbacktrack[i];
} else if (temp == maxHappinese && aveHappinese < temp/numOfVertex) {
aveHappinese = temp / numOfVertex;
maxHappVertex = Vbacktrack[i];
}
} cout << dist[end] << " " << count << " " << maxHappinese << " " << aveHappinese << endl; stack<int> pathToRom;
pathToRom.push(end);
while (path[maxHappVertex] != -1) {
pathToRom.push(maxHappVertex);
maxHappVertex = path[maxHappVertex];
}
cout << start;
while (!pathToRom.empty()) {
cout << "->" << NumToEn[pathToRom.top()];
pathToRom.pop();
}
cout << endl; return 0;
}

  

搞了半天就通过了一组数据。

1087 All Roads Lead to Rome的更多相关文章

  1. PAT 1087 All Roads Lead to Rome[图论][迪杰斯特拉+dfs]

    1087 All Roads Lead to Rome (30)(30 分) Indeed there are many different tourist routes from our city ...

  2. [图的遍历&多标准] 1087. All Roads Lead to Rome (30)

    1087. All Roads Lead to Rome (30) Indeed there are many different tourist routes from our city to Ro ...

  3. PAT 1087 All Roads Lead to Rome

    PAT 1087 All Roads Lead to Rome 题目: Indeed there are many different tourist routes from our city to ...

  4. PAT甲级1087. All Roads Lead to Rome

    PAT甲级1087. All Roads Lead to Rome 题意: 确实有从我们这个城市到罗马的不同的旅游线路.您应该以最低的成本找到您的客户的路线,同时获得最大的幸福. 输入规格: 每个输入 ...

  5. PAT 甲级 1087 All Roads Lead to Rome(SPFA+DP)

    题目链接 All Roads Lead to Rome 题目大意:求符合题意(三关键字)的最短路.并且算出路程最短的路径有几条. 思路:求最短路并不难,SPFA即可,关键是求总路程最短的路径条数. 我 ...

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

    时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Indeed there are many different ...

  7. PAT 甲级 1087 All Roads Lead to Rome

    https://pintia.cn/problem-sets/994805342720868352/problems/994805379664297984 Indeed there are many ...

  8. 1087 All Roads Lead to Rome (30)(30 分)

    Indeed there are many different tourist routes from our city to Rome. You are supposed to find your ...

  9. 1087 All Roads Lead to Rome (30 分)(最短路径)

    直接用Dijkstra做 #include<bits/stdc++.h> using namespace std; int n,m; map<string,int>si; ma ...

随机推荐

  1. windows server 2008 r2 AD域服务器设置

    域控制器是指在"域"模式下,至少有一台服务器负责每一台联入网络的电脑和用户的验证工作,相当于一个单位的门卫一样,称为"域控制器(Domain Controller,简写为 ...

  2. 翻译:《实用的Python编程》05_00_Overview

    目录 | 上一节 (4 类和对象) | 下一节 (6 生成器) 5. Python 对象的内部工作原理 本节介绍 Python 对象的内部工作原理.来自其它语言的程序员通常会发现 Python 的类概 ...

  3. 翻译:《实用的Python编程》05_01_Dicts_revisited

    目录 | 上一节 (4.4 异常) | 下一节 (5.2 封装) 5.1 再谈字典 Python 对象系统主要基于字典实现.本节将对此进行讨论. 字典 字典是命名值(named values)的集合. ...

  4. SpringBoot源码修炼—系统初始化器

    SpringBoot源码修炼-系统初始化器 传统SSM框架与SpringBoot框架简要对比 SSM搭建流程 缺点: 耗时长 配置文件繁琐 需要找合适版本的jar包 SpringBoot搭建流程 优点 ...

  5. 运用arcgis将标签图片(栅格图)转换为shp矢量文件

    最近在做图像分割校正,需要将ecognition分割好的shp文件做优化,但是如果直接对shp文件修改非常不友好,可以先对导出的tif标签图进行修改,然后将修改后的标签图转换为新的shp文件进行输出. ...

  6. Java面向对象(一些问题)

    2. Java 面向对象 2.1. 类和对象 2.1.1. 面向对象和面向过程的区别 面向过程 :面向过程性能比面向对象高. 因为类调用时需要实例化,开销比较大,比较消耗资源,所以当性能是最重要的考量 ...

  7. 在Windows10搭建WebAssembly开发环境

    最近研究WebAssembly技术,准备用WebAssembly编译C/C++代码供前端调用.网上看了很多文章,收获很大,现在就遇到的问题做一个记录. 官网关于windows开发环境搭建基本上几句话, ...

  8. Linux 自定义快捷命令

    Linux中一些比较常用的命令总是重复敲很麻烦,这个时候就可以使用 alias 来自定义快捷命令,用以简化操作.系统会有一些预定义的快捷命令,比如 ll 的效果就和 ls -l 一样. 可以使用 al ...

  9. PHP并发抢购解决方案

    Mysql版 逻辑步骤 mysql存储引擎使用Innodb 开始事务,查询商品库存并加上共享锁 判断库存是否足够,进行商品/订单/用户等操作 提交事务,完成下单抢购 代码参考 // 关闭自动提交 $t ...

  10. python多版本与虚拟环境

    这篇纯python技术文章,我自己平时也会用到,在此记录一下. 为什么会用到多个Python版本? 用macOS和Ubutntu的同学都知道系统默认安装的Python2.7.x,然后,我们平时pyth ...