\quad 这个题需要考虑很多因素,第一要求是找出花费最少的路,第二要求是在花费相同情况下找出happy值最高的路,第三要求是在花费和happy值都相同的情况下找出平均happy值最高的路,即经过最少的站点。故需要在子结构中层层判断并更新相应的数值。对了,我们还需要建立从名称到数字的映射和数字到名称的映射,程序如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 210;
int dis[maxn], inq[maxn], from[maxn]; //spfa里面记录路径长度,是否在队列中和具体路径的数组
int happy[maxn], total_happy[maxn], routeNum[maxn]; // 记录每个站点的happy,总的happy和路径条数
int stateNum[maxn]; //记录经过的站点数
map<int, string> mp;
map<string, int> rmp;
vector<pair<int, int> > E[maxn];
void spfa(int s, int t)
{
fill(dis, dis+maxn, 0x3f3f3f3f);
dis[s] = 0;
queue<int> q;
q.push(s);
inq[s] = 1;
routeNum[0] = 1; //注意路径条数初始化为1
stateNum[0] = 0;
total_happy[0] = 0;
while(!q.empty())
{
int u = q.front();
q.pop();
inq[u] = 0;
for (int i = 0; i < E[u].size(); ++i)
{
int v = E[u][i].first;
int w = E[u][i].second;
if(dis[u]+w<dis[v])
{
dis[v] = dis[u]+w;
from[v] = u;
total_happy[v] = happy[v]+total_happy[u];
routeNum[v] = routeNum[u];
stateNum[v] = stateNum[u]+1;
if(inq[v]==0)
{
q.push(v);
inq[v] = 1;
}
}
else if(dis[u]+w==dis[v])
{
routeNum[v] += routeNum[u];
if(total_happy[v]<total_happy[u]+happy[v])
{
total_happy[v] = total_happy[u]+happy[v];
from[v] = u;
stateNum[v] = stateNum[u]+1;
if(inq[v]==0)
{
q.push(v);
inq[v] = 1;
}
}
else if(total_happy[v]==total_happy[u]+happy[v])
{
if(stateNum[v]>stateNum[u]+1)
{
stateNum[v] = stateNum[u]+1;
from[v] = u;
if(inq[v]==0)
{
q.push(v);
inq[v] = 1;
}
}
}
}
}
}
int avr_happy = total_happy[t]/stateNum[t];
cout << routeNum[t] << " " << dis[t] << " " << total_happy[t] << " " << avr_happy << endl;
stack<int> st;
st.push(t);
int temp = from[t];
while(temp!=s)
{
st.push(temp);
temp = from[temp];
}
st.push(s);
while(!st.empty())
{
cout << mp[st.top()];
st.pop();
if(st.size()!=0) cout << "->";
}
}
int main(int argc, char const *argv[])
{
int n, k;
cin >> n >> k;
string start;
cin >> start;
mp[0] = start;
happy[0] = 0;
for (int i = 0; i < n-1; ++i)
{
string state;
int score;
cin >> state >> score;
happy[i+1] = score;
mp[i+1] = state;
rmp[state] = i+1;
}
for (int i = 0; i < k; ++i)
{
string u, v;
int w;
cin >> u >> v >> w;
E[rmp[u]].push_back(make_pair(rmp[v], w));
E[rmp[v]].push_back(make_pair(rmp[u], w));
}
int s = 0, t = rmp["ROM"];
spfa(s, t);
return 0;
}