这道题真的是目前为止见过的最有情怀的题目之一,感觉做完以后就不再爱北大了…
1、因为最后要求输出任意两个路径之间的最短距离,因此我选择使用的Floyd算法(数据比较弱,样例代码是贪心,应该也能过),Floyd算法用一个dis[N][N]数组存储任意两个点之间的距离,用path数组存储路径。
2、Floyd算法用的是动态规划的思想,设置初始数组为题目中所给的任意两个地点之间的距离, 然后每次更新这个二维数组,更新的思路是每次打开一个点k,比较从i到j经过点k的路径和不经过点k的路径,即dis[i][j] 和dis[i][k]+dis[k][j]的大小,取比较小的那个只更新到dis[i][j]中,若经过k比较短,则要更新path路径,把k存到path[i][j]中去,输出的时候再按照顺序找回去就可以了。
3、有个坑爹的地方在于连个地点之间的距离可能会出现多次,要取最短的存进去,然后图是无向图,因此存距离的时候dis[i][j]和dis[j][i]相等,查bug查了好久,果然还是刚接触这种数据结构经验不足。
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<limits.h>
using namespace std;
#define MAXP 33
string place[MAXP];
int dis[MAXP][MAXP]={0};
int path[MAXP][MAXP]={0};
int P,Q,R;
int getNum(string src){
for(int i=0;i<P;++i){
if(src==place[i]){
return i;
}
}
return -1;
}
void workP(){
scanf("%d",&P);
for(int i=0;i<P;++i){
for(int j=0;j<P;++j){
dis[i][j] = INT_MAX;
path[i][j] = -1;
}
}
for(int i=0;i<P;++i){
cin>>place[i];
}
for(int i=0;i<P;++i){
dis[i][i] = 0;
path[i][i] = i;
}
}
void debug(){
for(int i=0;i<P;++i){
for(int j=0;j<P;++j){
if(dis[i][j]==INT_MAX)
cout<<setw(4)<<"-1"<<' ';
else
cout<<setw(4)<<dis[i][j]<<' ';
}
cout<<endl;
}
cout<<endl;
}
void process(){
for(int k=0;k<P;++k){
for(int i = 0;i<P;++i){
for(int j=0;j<P;++j){
int dis1 = dis[i][j];
int dis2 = INT_MAX;
if(dis[i][k]!=INT_MAX && dis[k][j] != INT_MAX){
dis2 = dis[i][k]+dis[k][j];
}
if(dis2<dis1){
dis[i][j] = dis2;
path[i][j] = k;
}
}
}
//debug();
}
}
void workQ(){
scanf("%d",&Q);
while(Q--){
string p1,p2;
int dis0;
cin>>p1>>p2;
scanf("%d",&dis0);
int a = getNum(p1),b = getNum(p2);
if(dis0<dis[a][b]){
dis[a][b] = dis0;
dis[b][a] = dis0;
}
}
//debug();
process();
}
void output(int _x,int _y){
if (path[_x][_y] == -1){
cout << "->(" << dis[_x][_y] << ")->" << place[_y];
return;
}
output(_x, path[_x][_y]);
output(path[_x][_y], _y);
}
void workR(){
scanf("%d",&R);
while(R--){
string p1,p2;
cin>>p1>>p2;
int x = getNum(p1),y = getNum(p2);
if(x==y){
cout<<place[x]<<endl;
continue;
}
cout<<place[x];
output(x,y);
cout<<endl;
}
}
int main(){
workP();
//debug();
workQ();
workR();
//system("pause");
return 0;
}