照例先上题目:
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;
}