本題要求你實現一個天梯賽專屬在線地圖,隊員輸入自己學校所在地和賽場地點後,該地圖應該推薦兩條路線:一條是最快到達路線;一條是最短距離的路線。題目保證對任意的查詢請求,地圖上都至少存在一條可達路線。
輸入格式:
輸入在第一行給出兩個正整數N
(2 ≤ N
≤ 500)和M
,分別爲地圖中所有標記地點的個數和連接地點的道路條數。隨後M
行,每行按如下格式給出一條道路的信息:
V1 V2 one-way length time
其中V1
和V2
是道路的兩個端點的編號(從0到N
-1);如果該道路是從V1
到V2
的單行線,則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;
}