PTA 一 天梯地圖

本題要求你實現一個天梯賽專屬在線地圖,隊員輸入自己學校所在地和賽場地點後,該地圖應該推薦兩條路線:一條是最快到達路線;一條是最短距離的路線。題目保證對任意的查詢請求,地圖上都至少存在一條可達路線。

輸入格式:

輸入在第一行給出兩個正整數N(2 \le N \le 500)和M,分別爲地圖中所有標記地點的個數和連接地點的道路條數。隨後M行,每行按如下格式給出一條道路的信息:

V1 V2 one-way length time

其中V1V2是道路的兩個端點的編號(從0到N-1);如果該道路是從V1V2的單行線,則one-way爲1,否則爲0;length是道路的長度;time是通過該路所需要的時間。最後給出一對起點和終點的編號。

輸出格式:

首先按下列格式輸出最快到達的時間T和用節點編號表示的路線:

Time = T: 起點 => 節點1 => ... => 終點

然後在下一行按下列格式輸出最短距離D和用節點編號表示的路線:

Distance = D: 起點 => 節點1 => ... => 終點

如果最快到達路線不唯一,則輸出幾條最快路線中最短的那條,題目保證這條路線是唯一的。而如果最短距離的路線不唯一,則輸出途徑節點數最少的那條,題目保證這條路線是唯一的。

如果這兩條路線是完全一樣的,則按下列格式輸出:

Time = T; Distance = D: 起點 => 節點1 => ... => 終點

輸入樣例1:

10 15
0 1 0 1 1
8 0 0 1 1
4 8 1 1 1
5 4 0 2 3
5 9 1 1 4
0 6 0 1 1
7 3 1 1 2
8 3 1 1 2
2 5 0 2 2
2 1 1 1 1
1 5 0 1 3
1 4 0 1 1
9 7 1 1 3
3 1 0 2 5
6 3 1 2 1
5 3

輸出樣例1:

Time = 6: 5 => 4 => 8 => 3
Distance = 3: 5 => 1 => 3

輸入樣例2:

7 9
0 4 1 1 1
1 6 1 3 1
2 6 1 1 1
2 5 1 2 2
3 0 0 1 1
3 1 1 3 1
3 2 1 2 1
4 5 0 2 2
6 5 1 2 1
3 5

輸出樣例2:

Time = 3; Distance = 4: 3 => 2 => 5

算法思路:單源最短路徑拓展了一下

#include<stdio.h>
#include<stack>
using namespace std;

const int MAX = 1000000;
int mapl[500][500];
int mapt[500][500];
int vis[500];
int pre[500];
int dis[500];
int tim[500];
int n;

void init() {
	int i;
	for (i = 0; i<n; i++) {
		vis[i] = false;
		dis[i] = MAX;
		tim[i] = MAX;
	}
}

void dijkstraForTime(int source, int dest) {
	init();
	int i;
	int u = source;
	tim[u] = 0;
	dis[u] = 0;
	while (u != dest) {
		vis[u] = true;
		int tempt, templ;
		for (i = 0; i<n; i++) {
			if (vis[i])continue;
			tempt = mapt[u][i] + tim[u];
			templ = mapl[u][i] + dis[u];
			if (tempt<tim[i]) {
				tim[i] = tempt;
				dis[i] = templ;
				pre[i] = u;
			}
			else if (tim[i] != MAX&&tempt == tim[i]) {
				if (templ<dis[i]) {
					dis[i] = templ;
					pre[i] = u;
				}
			}
		}
		tempt = MAX;
		for (i = 0; i<n; i++) {
			if (!vis[i] && tempt>tim[i]) {
				tempt = tim[i];
				u = i;
			}
		}
	}
}

void dijkstraForLength(int source, int dest) {
	init();
	int i;
	int u = source;
	tim[u] = 1;
	dis[u] = 0;
	while (u != dest) {
		vis[u] = true;
		int tempt, templ;
		for (i = 0; i<n; i++) {
			if (vis[i])continue;
			tempt = 1 + tim[u];
			templ = mapl[u][i] + dis[u];
			if (templ<dis[i]) {
				tim[i] = tempt;
				dis[i] = templ;
				pre[i] = u;
			}
			else if (dis[i] != MAX&&templ == dis[i]) {
				if (tempt<tim[i]) {
					tim[i] = tempt;
					pre[i] = u;
				}
			}
		}
		templ = MAX;
		for (i = 0; i<n; i++) {
			if (!vis[i] && templ>dis[i]) {
				templ = dis[i];
				u = i;
			}
		}
	}
}

void getroad(int source, int dest, stack<int>& citys, int* pre) {
	int u = dest;
	while (u != source) {
		citys.push(u);
		u = pre[u];
	}
	citys.push(source);
}

bool judge(stack<int> a, stack<int> b) {
	int len1 = a.size();
	int len2 = b.size();
	if (len1 != len2) return false;
	while (len1--) {
		if (a.top() != b.top()) return false;
		a.pop();
		b.pop();
	}
	return true;
}

int main() {
	int m;
	scanf("%d%d", &n, &m);
	int i;
	for (i = 0; i<n; i++)
		for (int j = 0; j<n; j++)
		{
			mapl[i][j] = MAX;
			mapt[i][j] = MAX;
		}
	int v1, v2, style, length, time;
	for (i = 0; i<m; i++) {
		scanf("%d%d%d%d%d", &v1, &v2, &style, &length, &time);
		mapl[v1][v2] = length;
		mapt[v1][v2] = time;
		if (!style) {
			mapl[v2][v1] = length;
			mapt[v2][v1] = time;
		}
	}
	int source, dest, mintime, mindis;
	scanf("%d%d", &source, &dest);
	dijkstraForTime(source, dest);
	mintime = tim[dest];
	stack<int> troad;
	getroad(source, dest, troad, pre);
	dijkstraForLength(source, dest);
	mindis = dis[dest];
	stack<int> lroad;
	getroad(source, dest, lroad, pre);
	if (judge(lroad, troad))
	{
		printf("Time = %d; Distance = %d: %d", mintime, mindis, lroad.top());
		lroad.pop();
		while (!lroad.empty()) {
			printf(" => %d", lroad.top());
			lroad.pop();
		}
	}
	else {
		printf("Time = %d: %d", mintime, troad.top());
		troad.pop();
		while (!troad.empty()) {
			printf(" => %d", troad.top());
			troad.pop();
		}
		printf("\n");
		printf("Distance = %d: %d", mindis, lroad.top());
		lroad.pop();
		while (!lroad.empty()) {
			printf(" => %d", lroad.top());
			lroad.pop();
		}
	}
	printf("\n");
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章