照例先上題目:
1:我愛北大
查看 提交 統計 提問
總時間限制: 1000ms 內存限制: 65535kB
描述
“紅樓飛雪,一時英傑……”耳邊傳來了那熟悉的歌聲。而這,只怕是我最後一次聽到這個聲音了。
想當年,我們曾經懷着豪情壯志,許下心願,走過靜園,走過一體,走過未名湖畔的每個角落。
想當年,我們也曾慷慨高歌,瞻仰民主與科學,瞻仰博雅塔頂,那百年之前的遺韻。
沒錯,我愛北大,我愛這個校園。
然而,從當我們穿上學位服的那一刻起,這個校園,就再也不屬於我。它只屬於往事,屬於我的回憶。
沒錯,這,是我在北大的最後一日。此時,此景,此生,此世,將刻骨難忘。
再也沒有了圖書館自習的各種紛紜,再也沒有了運動場上的揮汗如雨,有的,只是心中永遠的不捨,與牽掛。
夜,已深。人,卻不願離去。天邊有一顆流星劃過,是那般靜,寧謐。
忍不住不回頭,我的眼邊,有淚光,劃過。
這時候,突然有一位路人甲從你身旁出現,問你:從XX到XX怎麼走?
索性,就讓我再愛你一次。因爲,北大永遠在你心中。北大的地圖,永遠在你的心中。
輕手揮揚,不帶走一分雲彩。
輸入
輸入分爲三個部分。
第一個部分有P+1行,第一行爲一個整數P,之後的P行表示北大的地點。
第二個部分有Q+1行,第一行爲一個整數Q,之後的Q行每行分別爲兩個字符串與一個整數,表示這兩點有直線的道路,並顯示二者之間的矩離(單位爲米)。
第三個部分有R+1行,第一行爲一個整數R,之後的R行每行爲兩個字符串,表示需要求的路線。
p<30,Q<50,R<20
輸出
輸出有R行,分別表示每個路線最短的走法。其中兩個點之間,用->(矩離)->相隔
樣例輸入
6
XueYiShiTang
CanYinZhongXin
XueWuShiTang
XueYiXiaoBaiFang
BaiNianJiangTang
GongHangQuKuanJi
6
XueYiShiTang CanYinZhongXin 80
XueWuShiTang CanYinZhongXin 40
XueYiShiTang XueYiXiaoBaiFang 35
XueYiXiaoBaiFang XueWuShiTang 85
CanYinZhongXin GongHangQuKuanJi 60
GongHangQuKuanJi BaiNianJiangTang 35
1
XueYiXiaoBaiFang BaiNianJiangTang
樣例輸出
XueYiXiaoBaiFang->(35)->XueYiShiTang->(80)->CanYinZhongXin->(60)->GongHangQuKuanJi->(35)->BaiNianJiangTang
提示
很O疼的一道題。。。說出不少傷感事啊。兩個最短路的算法都是可以用的,可以視情況選擇你習慣的那個算法。
Floyd算法解決任意兩點間最短路徑的問題。
代碼清單:
//Floyd最短路算法
#include <iostream>
#include <string>
using namespace std;
#include <map>
#include <stack>
#define MAXP 30
#define INFINITE 1000000
map<string, int> vertex_index; //將地名映射爲數字下標
map<int, string> index_vertex; //將數字下標映射爲地名
int map_index=0;
stack<int> trajectory; //記錄軌跡
int dist[MAXP][MAXP]; //記錄兩點最短距離
int pre[MAXP][MAXP]; //prev[x][y]:若x-->y已是最短距離,此值爲x;若通過中繼u,x-->u-->y更短,此值爲u。總之,儲存y的前驅頂點。
void init_dist(int p) //初始狀態,圖中都是孤立的點,沒有邊;自己到自己的距離爲0,到其他點的距離爲無窮大。
{
int i, j;
for (i=0; i<p; ++i)
for (j=0; j<p; ++j)
dist[i][j]=INFINITE;
for (i=0; i<p; ++i)
dist[i][i]=0;
}
void init_prev(int p) //孤立的點當然沒有前驅
{
int i, j;
for (i=0; i<p; ++i)
for (j=0; j<p; ++j)
pre[i][j]=-1;
}
void build_dist_and_prev(string from, string to, int _dist)
{
if (vertex_index.count(from)==0)
{
vertex_index[from]=map_index;
index_vertex[map_index]=from;
++map_index;
}
if (vertex_index.count(to)==0)
{
vertex_index[to]=map_index;
index_vertex[map_index]=to;
++map_index;
}
int i=vertex_index[from];
int j=vertex_index[to];
dist[i][j]=_dist;
dist[j][i]=_dist;
pre[i][j]=i;
pre[j][i]=j;
}
//Floyd最短路核心代碼
void run_floyd(int p)
{
int i, j, k; //k爲可能縮短距離的中繼頂點
for (k=0; k<p; ++k)
{
for (i=0; i<p; ++i)
{
for (j=0; j<p; ++j)
{
if( dist[i][j] > dist[i][k]+dist[k][j] ) //relaxation
{
dist[i][j]=dist[i][k]+dist[k][j];
pre[i][j]=pre[k][j];
}
}
}
}
}
void query_shortest_path(string from, string to)
{
int i=vertex_index[from];
int j=vertex_index[to];
int k=j;
int prev_node, tmp;
do
{
trajectory.push(k);
k=pre[i][k];
} while (k!=i);
cout<<from;
prev_node=vertex_index[from];
while (!trajectory.empty())
{
tmp=trajectory.top();
cout<<"->("<<dist[prev_node][tmp]<<")->"<<index_vertex[tmp];
prev_node=tmp;
trajectory.pop();
}
cout<<endl;
}
int main()
{
//freopen("D:\\in.txt", "r", stdin);
//freopen("D:\\out.txt", "w", stdout);
int p, q, r;
string from, to;
int _dist;
cin>>p;
init_dist(p);
init_prev(p);
for (int i=0; i<p; ++i) //沒用
{
cin>>from;
}
cin>>q;
for (int i=0; i<q; ++i)
{
cin>>from;
cin>>to;
cin>>_dist;
build_dist_and_prev(from, to, _dist);
}
run_floyd(p);
cin>>r;
for (int i=0; i<r; ++i)
{
cin>>from;
cin>>to;
query_shortest_path(from, to);
}
return 0;
}