#include<unordered_map>
#include<bitset>
#include<iostream>
#include<string>
#include<vector>
using namespace std;
const int N=300;
int pos;
string name[300];
int s2i(string s)
{
static unordered_map<string,int>nth;
auto it=nth.find(s);
if(it!=nth.end())
return it->second;
else{
name[pos]=s;
nth[s]=pos;
return pos++; }
}
struct node{int to,len;node(int a,int b):to(a),len(b){}};
vector<node>ed[N];
int dis[N],pre[N],allval[N],used[N],num[N],cnt[N];
int src,dst,val[N];
void dijkstra()
{
fill_n(dis,N,1<<30);
dis[src]=0;
allval[src]=val[src];
num[src]=0;
cnt[src]=1;
while(true)
{
int next=-1;
for(int mmin=1<<30,i=0;i<pos;++i)
if(!used[i]&&dis[i]<mmin) mmin=dis[next=i];
if(next==-1)break;
used[next]=true;
for(auto x:ed[next])
if(!used[x.to])
{
if(dis[x.to]>dis[next]+x.len)
{
cnt[x.to]=cnt[next];
dis[x.to]=dis[next]+x.len;
pre[x.to]=next;
allval[x.to]=allval[next]+val[x.to];
num[x.to]=num[next]+1;
}else if(dis[x.to]==dis[next]+x.len)
{
cnt[x.to]+=cnt[next];
if(allval[x.to]<allval[next]+val[x.to]||
allval[x.to]==allval[next]+val[x.to]&&
(num[x.to]>num[next]+1))
{
pre[x.to]=next;
allval[x.to]=allval[next]+val[x.to];
num[x.to]=num[next]+1;
}//if
}//else if
}//if
}//while
}
void path(int k){
if(k!=src) path(pre[k]);
static int first=0;
cout<<(first++?"->":"")<<name[k];
}
int main(){
dst=s2i("ROM");
int n,k;
string sa,sb;
cin>>n>>k>>sa;
src=s2i(sa);
for(int i=1,tmp;i<n;++i)
{cin>>sa>>tmp; val[s2i(sa)]=tmp; }
for(int i=0,len,t1,t2;i<k;++i){
cin>>sa>>sb>>len;
t1=s2i(sa),t2=s2i(sb);
ed[t1].emplace_back(t2,len);
ed[t2].emplace_back(t1,len);
}
dijkstra();
printf("%d %d %d %d\n",cnt[dst],dis[dst],allval[dst],allval[dst]/num[dst]);
path(dst);
}
dijkstra算法,不过平常在松弛路径是只要保持pre,dis,used就行,这里还要保持最短路径数cnt,最短路径上最多城市数num,最短路径上最大累计happy值allval,其他的没什么,注意cnt的更新方式即可