PAT A1087 All Roads Lead to Rome
思路:可采用Dijkstra或Dijkstra + DFS的做法。
使用Dijkstra时注意优先处理最短路径,其次是幸福值,最后是平均幸福值。
打印路径时可以通过一维pre数组递归得到。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<map>
#include<string>
using namespace std;
const int MAXN = 205;
const int INF = 1E9;
int G[MAXN][MAXN], weight[MAXN], d[MAXN];
int happy[MAXN], pt[MAXN], pre[MAXN], num[MAXN];
bool visit[MAXN];
map<int, string> Int2Str;
map<string, int> Str2Int;
int N, K;
void Dijkstra(int s) {
fill(d, d + MAXN, INF);
d[s] = 0;
happy[s] = weight[s];
num[s] = 1;
for(int i = 0; i < N; i++) {
int u = -1, MIN = INF;
for(int j = 0; j < N; j++)
if(!visit[j] && d[j] < MIN) {
u = j;
MIN = d[j];
}
if(u == -1) return;
visit[u] = true;
for(int v = 0; v < N; v++)
if(!visit[v] && d[u] + G[u][v] < d[v]) {
d[v] = d[u] + G[u][v];
happy[v] = happy[u] + weight[v];
num[v] = num[u];
pt[v] = pt[u] + 1;
pre[v] = u;
} else if(!visit[v] && d[u] + G[u][v] == d[v]) {
num[v] += num[u];
if(happy[u] + weight[v] > happy[v]) {
happy[v] = happy[u] + weight[v];
pt[v] = pt[u] + 1;
pre[v] = u;
} else if(happy[u] + weight[v] == happy[v]) {
double uAvg = 1.0 * (happy[u] + weight[v]) / (pt[u] + 1);
double vAvg = 1.0 * happy[v] / pt[v];
if(uAvg > vAvg) {
pt[v] = pt[u] + 1;
pre[v] = u;
}
}
}
}
}
void printPath(int v) {
if(v == 0) {
cout << Int2Str[v];
return;
}
printPath(pre[v]);
cout << "->" << Int2Str[v];
}
int main() {
string city1, city2;
cin >> N >> K >> city1;
Str2Int[city1] = 0;
Int2Str[0] = city1;
for(int i = 1; i <= N - 1; i++) {
cin >> city1 >> weight[i];
Int2Str[i] = city1;
Str2Int[city1] = i;
}
int w, id1, id2;
fill(G[0], G[0] + MAXN * MAXN, INF);
for(int i = 0; i < K; i++) {
cin >> city1 >> city2 >> w;
id1 = Str2Int[city1];
id2 = Str2Int[city2];
G[id1][id2] = G[id2][id1] = w;
}
Dijkstra(0);
int id_rom = Str2Int["ROM"];
printf("%d %d %d %d\n", num[id_rom], d[id_rom], happy[id_rom], happy[id_rom] / pt[id_rom]);
printPath(id_rom);
return 0;
}