分析:利用map将string与int互相映射,再用Dijkstra+Dfs,注意路径不唯一的时候先取最大happiness,再取经过的城市更少的那条。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
#include<cstring>
using namespace std;
const int inf = 0x3f3f3f3f;
map<int, string> numCity;
map<string, int> cityNum;
vector<int> e[210], tempath, path;
int n, k, tem, tot, cnt = 1, mind = inf, maxh = 0, minl = inf, st = 1, ed = 1;
int happiness[210], cost[210][210], vis[210];
void dijkstra(int st, int ed){
int d[210];
memset(d, inf, sizeof d);
d[st] = 0;
for(int i = 1; i<=n; i++){
int u = -1, minn = inf;
for(int j = 1; j<=n; j++){
if(d[j] < minn && !vis[j]){
minn = d[u = j];
}
}
if(u == -1) break;
vis[u] = 1;
for(int v = 1; v<=n; v++){
if(d[u] + cost[u][v] < d[v]){
d[v] = d[u]+cost[u][v];
}
}
}
mind = d[ed];
}
void dfs(int u, int suml, int sumd, int sumh){
if(sumd > mind) return ;
else if(sumd == mind && u == ed){
tot++;
if(sumh == maxh){
if(suml < minl){
minl = suml;
path = tempath;
}
} else if(sumh > maxh){
minl = suml;
maxh = sumh;
path = tempath;
}
return;
}
for(int i = 0; i<e[u].size(); i++){
int v = e[u][i];
if(!vis[v]){
vis[v] = 1;
tempath.push_back(v);
dfs(v, suml+1, sumd+cost[u][v], sumh+happiness[v]);
tempath.pop_back();
vis[v] = 0;
}
}
}
int main(){
//freopen("aa.txt", "r", stdin);
ios::sync_with_stdio(false);
string start, str, str2;
cin >> n >> k >> start;
cityNum[start] = 1;
numCity[1] = start;
for(int i = 2; i<n+1; i++){
cin >> str >> happiness[i];
cityNum[str] = i;
numCity[i] = str;
}
ed = cityNum["ROM"];
memset(cost, inf, sizeof cost);
for(int i = 0; i<k; i++){
cin >> str >> str2 >> tem;
int u = cityNum[str], v = cityNum[str2];
cost[u][v] = cost[v][u] = tem;
e[u].push_back(v), e[v].push_back(u);
}
dijkstra(st, ed);
memset(vis, 0, sizeof vis);
vis[st] = 1;
tempath.push_back(st);
dfs(st, 0, 0, 0);
cout << tot << " " << mind << " " << maxh << " " << maxh/minl << '\n';
for(int i = 0; i<path.size(); i++){
cout << numCity[path[i]];
i != path.size()-1 ? cout << "->" : cout << "\n";
}
return 0;
}