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 1Sample Output:
3 3 195 97 HZH->PRS->ROM
#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#include<map>
using namespace std;
int happy[202];
int cost[202][202];
struct record{
int citys;//表示從起點開始經過的城市數目
int parent;//表示上一個節點
int average;//表示平均的開心數
int happy_all;//表示此條路徑的開心總數
record() :citys(0), parent(-1), average(-1) {}
};
bool mark[202];
int dist[202];
int happy_sum[202];
vector<record*>vec[202];
map<string, int>S2I;//字符串轉化爲數字
map<int, string>I2S;//數字轉化爲字符串
void dij(int s, int t,int city_num){
mark[s] = true;
dist[s] = 0;
happy_sum[s] = happy[s];
int newP = s;
record *rec_s = new record();
rec_s->citys = 1;
rec_s->parent = -1;
rec_s->happy_all = happy[s];
rec_s->average = rec_s->happy_all / rec_s->citys;
vec[s].push_back(rec_s);
while (!mark[t]){
for (int i = 0; i < city_num; ++i){
if (cost[newP][i] == -1 || cost[newP][i] == 0 || mark[i])continue;
else if (dist[i] == -1 || dist[i] > dist[newP] + cost[newP][i]){
//如果有更小距離的,那麼把vec清空,並且根據newP節點的所有路徑構建record
dist[i] = dist[newP] + cost[newP][i];
vec[i].clear();
//happy_sum[i] = happy_sum[newP] + happy[i];
for (int j = 0; j < vec[newP].size(); j++){
record *rec = new record();
rec->citys = vec[newP][j]->citys + 1;
rec->parent = newP;
rec->happy_all = vec[newP][j]->happy_all + happy[i];
//rec->average = happy_sum[i] / (rec->citys - 1);
rec->average = rec->happy_all / (rec->citys - 1);
vec[i].push_back(rec);
}
}
else if (dist[i] == dist[newP] + cost[newP][i]){
//如果最短距離相同,則構造record添加到vec中
for (int j = 0; j < vec[newP].size(); j++){
record *rec = new record();
rec->citys = vec[newP][j]->citys + 1;
rec->parent = newP;
rec->happy_all = vec[newP][j]->happy_all + happy[i];
rec->average = rec->happy_all / (rec->citys - 1);
vec[i].push_back(rec);
}
}
}
int min = 0x7fffffff;
for (int i = 0; i < city_num; ++i){
if (mark[i] || dist[i] == -1)continue;
if (dist[i] < min){
min = dist[i];
newP = i;
}
}
mark[newP] = true;
}//while
}
void printPath(int start_city, int end_city, int max_idx){
//打印路徑
if (end_city != start_city){
int parent = vec[end_city][max_idx]->parent;
int parent_max = 0;
int max = 0;
int happy_max = 0;
for (int i = 0; i < vec[parent].size(); ++i){
if (vec[parent][i]->happy_all > happy_max || (vec[parent][i]->happy_all == happy_max && vec[parent][i]->average > max)){
parent_max = i;
max = vec[parent][i]->average;
happy_max = vec[parent][i]->happy_all;
}
}
printPath(start_city, parent, parent_max);
cout << I2S[parent] << "->";
}
}
int main(){
freopen("F://Temp/input.txt", "r", stdin);
int city_num, road_num;
for (int i = 0; i < 202; i++){
happy[i] = 0;
dist[i] = -1;
mark[i] = false;
happy_sum[i] = 0;
vec[i].clear();
for (int j = 0; j < 202; ++j)
cost[i][j] = -1;
cost[i][i] = 0;
}
S2I.clear();
I2S.clear();
string start_city_str;
int start_city;
cin >> city_num >> road_num >> start_city_str;
int idx = 0;
if (S2I.find(start_city_str) == S2I.end()){
S2I[start_city_str] = idx;
I2S[idx] = start_city_str;
start_city = idx;
idx++;
}
for (int i = 0; i < city_num - 1; ++i){
string str_input;
int happy_input;
cin >> str_input >> happy_input;
if (S2I.find(str_input) == S2I.end()){
S2I[str_input] = idx;
I2S[idx] = str_input;
happy[idx] = happy_input;
idx++;
}
}
for (int i = 0; i < road_num; ++i){
string str_start, str_end;
int cost_input;
cin >> str_start >> str_end >> cost_input;
cost[S2I[str_start]][S2I[str_end]] = cost[S2I[str_end]][S2I[str_start]] = cost_input;
}
int end_city = S2I["ROM"];
dij(start_city,end_city,city_num);
int max_idx = 0;
int max = 0;
int happy_max = 0;
for (int i = 0; i < vec[end_city].size(); ++i){
if (vec[end_city][i]->happy_all > happy_max || (vec[end_city][i]->happy_all == happy_max && vec[end_city][i]->average > max)){
//這裏的判斷條件一定要寫對,詳見附圖,因爲有happy總數不一樣,而平均happy數一樣的情況
//我第一次寫的是vec[end_city][i]->happy_all > happy_max && vec[end_city][i]->average > max出錯了
max_idx = i;
max = vec[end_city][i]->average;
happy_max = vec[end_city][i]->happy_all;
}
}
cout << vec[end_city].size() << " " << dist[end_city] << " " << happy_max << " " << max << endl;
printPath(start_city, end_city, max_idx);
cout << "ROM" << endl;
return 0;
}
#include <iostream>
#include <cstdio>
#include <map>
#include <string>
#include <vector>
#include <climits>
using namespace std;
//每個城市結點
struct Edge
{
int cost;
int next;
};
struct Node
{
int value;
string str;
vector<Edge> next;
int distant, happy; // 第i個結點距離起始城市的最小距離和最大happy
int rNums; // 到第i個結點的最短路徑的條數
int pNums; // 到第i個結點最大幸福經歷的最少結數
bool visit;
int parent; //最大幸福的前一個結點,
Node():distant(INT_MAX), happy(0), rNums(INT_MAX), pNums(0), visit(false), parent(-1)
{
next.clear();
}
};
const int N = 201;
map<string, int> mp; //城市名字到結點編號的映射
Node node[N]; //
int seq[N];
int main(void)
{
int n, k;
scanf("%d%d", &n, &k);
string startS;
cin >> startS;
mp[startS] = 0;
node[0].value = 0;
node[0].distant = 0;
node[0].rNums = 0;
node[0].pNums = 1;
node[0].str = startS;
string city;
int value;
for (int i = 1; i < n; ++i)
{
cin >> city >> value;
mp[city] = i;
node[i].value = value;
node[i].str = city;
}
string city1, city2;
int c1, c2;
Edge edge;
for (int i = 0; i < k; ++i)
{
cin >> city1 >> city2 >> edge.cost;
c1 = mp[city1];
c2 = mp[city2];
edge.next = c2;
node[c1].next.push_back(edge);
edge.next = c1;
node[c2].next.push_back(edge);
}
city = "ROM";
int romIndex = mp[city];
while (true)
{
int minIndex = -1, minDistant = INT_MAX;
for (int i = 0; i < n; ++i)
{
if (node[i].visit == false && node[i].distant < minDistant)
{
minIndex = i;
minDistant = node[i].distant;
}
}
if (minIndex == -1)
break;
node[minIndex].visit = true;
if (minIndex == romIndex)
break;
for (vector<Edge>::iterator iter = node[minIndex].next.begin(); iter != node[minIndex].next.end(); ++iter)
{
if (node[iter->next].visit == true)
continue;
else
{
if (node[minIndex].distant + iter -> cost < node[iter -> next].distant)
{
node[iter -> next].distant = node[minIndex].distant + iter -> cost;
node[iter -> next].parent = minIndex;
node[iter -> next].happy = node[minIndex].happy + node[iter -> next].value;
node[iter -> next].pNums = node[minIndex].pNums;
node[iter -> next].rNums = node[minIndex].rNums + 1;
}
else if (node[minIndex].distant + iter -> cost == node[iter -> next].distant)
{
node[iter -> next].pNums += node[minIndex].pNums;
if ((node[iter -> next].happy < node[minIndex].happy + node[iter -> next].value))
{
node[iter -> next].happy = node[minIndex].happy + node[iter -> next].value;
node[iter -> next].rNums = node[minIndex].rNums + 1;
node[iter -> next].parent = minIndex;
}
}
}
}
}
printf("%d %d %d %d\n", node[romIndex].pNums, node[romIndex].distant, node[romIndex].happy, node[romIndex].happy / node[romIndex].rNums);
int index = 0;
while (romIndex != -1)
{
seq[index++] = romIndex;
romIndex = node[romIndex].parent;
}
--index;
cout << node[seq[index]].str;
for (int i = index - 1; i >= 0; --i)
{
printf("->");
cout << node[seq[i]].str;
}
printf("\n");
return 0;
}