openjudge 我爱北大

照例先上题目:

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;
}


你可能感兴趣的:(最短路径,图,邻接矩阵,OpenJudge,Floyd算法)