这个题就是求最短路径, 然而还有一些限制条件就是最短路一样的时候顶点的欢乐值要最大, 欢乐值一样的时候路径上顶点的个数要最小(不包括源点), 另外要顺带求出最短路径的个数。 实现的时候我们可以用优先队列来优化dijkstra算法, 每更新一个数值其他的也要相应的更新, 另外在求解路径个数的时候假设我们以rout[u]表示最短到达u的最短路的个数, 那么对于d[v] > d[u] + c的时候就有rout[v] = rout[u], d[v]==d[u]+c就有rout[v]+=rout[u];代码如下:
#include <cstdio> #include <algorithm> #include <cstring> #include <map> #include <string> #include <vector> #include <iostream> #include <queue> using namespace std; int N, M; int vm[210]; map<string, int> str2int; vector<string> int2str; struct edge{ int to, c; }; vector<edge> G[210]; bool vis[210]; int rout[210]; //路径个数 int d[210]; //最短路径 int hpy[210]; //欢乐值 int geshu[210]; //到v的顶点的个数 int pre[210]; struct Dij { int u, c; bool operator < (const Dij&r) const { return c > r.c; } }; void dijkstra() { memset(vis, 0, sizeof(vis)); memset(d, 0x3f, sizeof(d)); memset(rout, 0, sizeof(rout)); memset(hpy, -1, sizeof(hpy)); memset(geshu, 0x3f, sizeof(geshu)); d[0] = 0; rout[0]=1; hpy[0]=0; geshu[0]=0; pre[0] = -1; priority_queue<Dij> que; que.push((Dij){0, 0}); while(!que.empty()) { Dij tp = que.top(); que.pop(); int u = tp.u; if(vis[u]) continue; vis[u] = 1; for(int i=0; i<G[u].size(); i++) { int v = G[u][i].to, c = G[u][i].c; if(d[v]>d[u]+c) { d[v] = d[u]+c; que.push((Dij){v, d[v]}); rout[v] = rout[u]; hpy[v] = hpy[u]+vm[v]; geshu[v] = geshu[u]+1; pre[v] = u; } else if(d[v]==d[u]+c && hpy[u]+vm[v]>hpy[v]) { rout[v] += rout[u]; hpy[v] = hpy[u]+vm[v]; geshu[v] = geshu[u]+1; pre[v] = u; } else if(d[v]==d[u]+c&&hpy[u]+vm[v]==hpy[v]&&geshu[u]+1<geshu[v]) { rout[v] += rout[u]; geshu[v] = geshu[u]+1; pre[v] = u; } else if(d[v]==d[u]+c) rout[v] += rout[u]; } } } int main() { cin>>N>>M; string str; cin>>str; str2int[str] = 0; int2str.push_back(str); vm[0] = 0; for(int i=1; i<N; i++) { string uu; int t; cin>>uu>>t; str2int[uu] = i; int2str.push_back(uu); vm[i] = t; } for(int i=0; i<M; i++) { string uu, vv; int t; int u, v; cin>>uu>>vv>>t; u = str2int[uu]; v = str2int[vv]; G[u].push_back((edge){v, t}); G[v].push_back((edge){u, t}); } dijkstra(); int t = str2int["ROM"]; cout<<rout[t]<<' '<<d[t]<<' '<<hpy[t]<<' '<<hpy[t]/geshu[t]<<endl; vector<int> e; int u = t; while(u!=-1) { e.push_back(u); u = pre[u]; } for(int i=e.size()-1; i>=0; i--) { if(i==0) cout<<int2str[e[i]]<<endl; else cout<<int2str[e[i]]<<"->"; } return 0; }