从我们的城市到达罗马有许多不同的旅游路线。
请你在成本最低的旅游路线之中,找到使得游客幸福感最强的路线。
输入格式
第一行包含两个整数 NN 和 KK,分别表示总城市数量,城市之间道路数量,还包含一个城市名字,表示初始城市。
接下来 N−1N−1 行,每行包含一个城市名和一个整数,表示到达该城市(初始城市除外)可以获得的幸福感。
接下来 KK 行,每行包含一个道路的信息,格式为 City1 City2 Cost,表示两个城市之间的道路行走的花费,道路是双向的。
城市都是由三个大写字母构成的字符串。
我们的目的地始终都是罗马 ROM。
输出格式
我们应该找到成本最低的路线。
如果这样的路线不是唯一的,那么选取使人们获得最大幸福感的路线。
如果这样的路线仍然不是唯一的,那么我们选择平均幸福感最大的路线,数据保证这种路线唯一。
平均幸福感 = 总幸福感 / 经过的城市数量(初始城市不算)
第一行输出四个整数,最小成本的路线数量,最小成本,幸福感,平均幸福感(只取整数部分)。
第二行,按照 City1->City2->…->ROM 的格式输出路线。
数据范围
2≤N≤2002≤N≤200,
1≤K≤2501≤K≤250,
每个城市的幸福感范围在 [0,100][0,100],
每条路线最大成本不超过 10001000
输入样例:
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
输出样例:
3 3 195 97
HZH->PRS->ROM
#include<bits/stdc++.h>
using namespace std;
const int N=250;
int g[N][N],w[N];
int n,m;
int dist[N],weight[N],cnt[N],sum[N],pre[N];//sum记录点数 平均幸福感最大点数最小路线
bool st[N];
unordered_map<string, int>mp1;
unordered_map<int, string>mp2;
void dijiskstra(){
memset(dist,0x3f,sizeof dist);
dist[1]=0;
sum[1]=0;//初始城市不算
cnt[1]=1;
for(int i=0;i<n;i++){ //循环n次
int t=-1;
for(int j=1;j<=n;j++){
if(!st[j]&&(t==-1||dist[j]<dist[t]))
t=j;
}
if(t==-1)break;
st[t]=true;
for(int v=1;v<=n;v++){
if(dist[t]+g[t][v]<dist[v]){
dist[v]=dist[t]+g[t][v];
pre[v]=t;
cnt[v]=cnt[t];
weight[v]=weight[t]+w[v];
sum[v]=sum[t]+1;
}
else if(dist[t]+g[t][v]==dist[v]){
cnt[v]+=cnt[t]; //无论如何都得加
if(weight[t]+w[v]>weight[v]){ //幸福感
weight[v]=weight[t]+w[v];
pre[v]=t;
sum[v]=sum[t]+1;
}
else if(weight[t]+w[v]==weight[v]) {
if(sum[t]+1<sum[v]){ //平均幸福感
pre[v]=t;
sum[v]=sum[t]+1;
}
}
}
}
}
}
int main(){
cin>>n>>m;
string s;
cin>>s;
mp1[s]=1;
mp2[1]=s;
for(int i=2;i<=n;i++){
string b;
int c;
cin>>b>>c;
mp1[b]=i;
mp2[i]=b;
w[i]=c;//点权
}
memset(g,0x3f,sizeof g);//记得初始化
for(int i=0;i<m;i++){
string a,b;
int c;
cin>>a>>b>>c;
int t1=mp1[a];
int t2=mp1[b];
g[t1][t2]=g[t2][t1]=min(c,g[t1][t2]);
}
dijiskstra();
int T=mp1["ROM"];
cout<<cnt[T]<<' '<<dist[T]<<' '<<weight[T]<<' '
<<weight[T]/sum[T]<<endl;
cout<<mp2[1];
vector<int> v;
for(int i=T;i!=1;i=pre[i]){
v.push_back(i);
}
for(int i=v.size()-1;i>=0;i--){
cout<<"->"<<mp2[v[i]];
}
return 0;
}