PAT A1087 All Roads Lead to Rome
- dj里面的条款还是记不太清,反正是需要不断更新和比较的维度都要用数组去装
- 增加新的维度以后,起点处的初始化也要增加相应的维度
- 填充的值别搞错(0,INF,false,pre[i] = i)
- 本题平均值的维度符合局部最优,对比自行车管理那道题
- 路径条数是从1开始的,而顶点数是从0开始的,因为起点不happy,算均值时没有他
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <math.h>
#include <set>
#include <map>
#include <unordered_map>
#include <stack>
using namespace std;
#define MAXSIZE 233
#define INF 999999999
int G[MAXSIZE][MAXSIZE],weight[MAXSIZE],dist[MAXSIZE],pre[MAXSIZE],w[MAXSIZE],pnum[MAXSIZE],vnum[MAXSIZE];
bool visited[MAXSIZE] = {false};
int cnum,rnum;
string idx_to_name[MAXSIZE];
unordered_map<string,int> umap;
stack<string> stk;
void dj(int s){
fill(dist,dist + MAXSIZE,INF);
fill(visited,visited + MAXSIZE,false);
for(int i = 0;i < cnum;i ++) pre[i] = i;
dist[s] = 0;
w[s] = weight[s];
pnum[s] = 1;
for(int i = 0;i < cnum;i ++){
int u = -1,min = INF;
for(int j = 0;j < cnum;j ++){
if(!visited[j] && dist[j] < min){
min = dist[j];
u = j;
}
}
if(u == -1) return;
visited[u] = true;
for(int v = 0;v < cnum;v ++){
if(!visited[v] && G[u][v] != INF){
if(dist[v] > dist[u] + G[u][v]){
dist[v] = dist[u] + G[u][v];
w[v] = w[u] + weight[v];
pre[v] = u;
pnum[v] = pnum[u];
vnum[v] = vnum[u] + 1;
}else if(dist[v] == dist[u] + G[u][v]){
pnum[v] += pnum[u];
if(w[v] < w[u] + weight[v]){
w[v] = w[u] + weight[v];
pre[v] = u;
vnum[v] = vnum[u] + 1;
}else if(w[v] == w[u] + weight[v]){
double avg_wv = 1.0 * w[v] / vnum[v];
double avg_new = 1.0 * w[v] / (vnum[u] + 1);
if(avg_wv < avg_new){
pre[v] = u;
vnum[v] = vnum[u] + 1;
}
}
}
}
}
}
}
#define DEBUG 1
int main(){
#ifdef DEBUG
freopen("1.txt","r",stdin);
#endif
string start;
cin >> cnum >> rnum >> start;
fill(G[0],G[0] + MAXSIZE * MAXSIZE,INF);
umap[start] = 0;
idx_to_name[0] = start;
for(int i = 1;i < cnum;i ++){
string name;
cin >> name >> weight[i];
umap[name] = i;
idx_to_name[i] = name;
}
for(int i = 0;i < rnum;i ++){
string n1,n2;
int cost;
cin >> n1 >> n2 >> cost;
G[umap[n1]][umap[n2]] = G[umap[n2]][umap[n1]] = cost;
}
dj(umap[start]);
int dst = umap["ROM"];
cout << pnum[dst] << ' ' << dist[dst] << ' ' << w[dst] << ' ' << w[dst] / vnum[dst] << endl;
int p = dst;
do{
stk.push(idx_to_name[p]);
p = pre[p];
}while(p != umap[start]);
cout << start;
while(!stk.empty()){
cout << "->" << stk.top();
stk.pop();
}
return 0;
}