这里只说明关键部分。
有三个优先级,由高到低分别是:
距离、高兴值、平均高兴值。
距离即是最普通的Dijkstra所求的目标。
高兴值是点权变体之一。
平均高兴值可化为求最短路径中的最少结点路径,也属于点权变体之一。
在更新结果的代码中,优先级高的更新的结果要更多。
所有优先级低的更新时必须保证比它更高优先级的结果是一致的。
下面放代码:(PS,怎么感觉最近这么多Dijkstra。。。)
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<map> using namespace std; map<string, int> str2int; map<int, string> int2str; const int M = 210; const int INF = INT32_MAX; int n, e, G[M][M], vertex[M]; int num[M], path[M], dist[M],happy[M],node[M]; bool vis[M]; string start; int cur = -1; int change(string city) { if (str2int.find(city) != str2int.end()) { return str2int[city]; } cur++; str2int[city] = cur; int2str[cur] = city; return cur; } void initGraph() { fill(G[0],G[0]+M*M,INF); cin >> n >> e>>start; string c1, c2; int idc1, idc2, ele; vertex[change(start)] = 0; for (int i = 0; i < n-1; i++) { cin >> c1 >> ele; vertex[change(c1)]=ele; } for (int i = 0; i < e; i++) { cin >> c1 >> c2 >> ele; idc1 = change(c1); idc2 = change(c2); G[idc1][idc2] = G[idc2][idc1] = ele; } } void Dijkstra() { fill(dist,dist+n,INF); for (int i = 1; i < n; i++) { path[i] = i; } int s = str2int[start]; dist[s] = 0; num[s] = 1; int k, m; for (int i = 0; i < n; i++) { k = -1, m = INF; for (int j = 0; j < n; j++) { if (!vis[j] && dist[j]<m) { m = dist[j]; k = j; } } if (k==-1) { return; } else { vis[k] = true; } for (int j = 0; j < n; j++) { if (!vis[j] && G[k][j]!=INF) { if (dist[k]+G[k][j]<dist[j]) { dist[j] = dist[k] + G[k][j]; path[j] = k; num[j] = num[k]; happy[j] = happy[k] + vertex[j]; node[j] = node[k]+1; } else if (dist[k] + G[k][j] == dist[j]) { num[j] += num[k]; if (happy[k]+vertex[j]>happy[j]) { happy[j] = happy[k] + vertex[j]; node[j] = node[k] + 1; path[j] = k; } else if (happy[k] + vertex[j] == happy[j] && node[j] > node[k] + 1) { node[j] = node[k] + 1; path[j] = k; } } } } } } void printPath(int s,int d,string &r) { if (s==d) { r.append(int2str[d]); r.append("->"); return; } printPath(s,path[d],r); r.append(int2str[d]); r.append("->"); } int main() { initGraph(); Dijkstra(); int s = str2int[start]; int d = str2int["ROM"]; cout << num[d] <<" "<< dist[d]<<" "<<happy[d]<<" "<<happy[d]/node[d]<<endl; string r; printPath(s,d,r); cout << r.substr(0,r.size()-2); int a = 0; return 0; }