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


發佈了50 篇原創文章 · 獲贊 16 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章