這道題真的是目前爲止見過的最有情懷的題目之一,感覺做完以後就不再愛北大了…
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;
}