題目:
已知2條地鐵線路,其中A爲環線,B爲東西向線路,線路都是雙向的。經過的站點名分別如下,兩條線交叉的換乘點用T1、T2表示。編寫程序,任意輸入兩個站點名稱,輸出乘坐地鐵最少需要經過的車站數量(含輸入的起點和終點,換乘站點只計算一次)。
地鐵線A(環線)經過車站:
A1 A2 A3 A4 A5 A6 A7 A8 A9 T1 A10 A11 A12 A13 T2 A14 A15 A16 A17 A18
地鐵線B(直線)經過車站:
B1 B2 B3 B4 B5 T1 B6 B7 B8 B9 B10 T2 B11 B12 B13 B14 B15
本題可用Floyed算法解決。先求出每相鄰兩點的權值(這裏是1,因爲相鄰的站就相差1個站),然後窮舉所有點,若存在點k使距離(i,k)+距離(k,j)<距離(i,j),則更新距離(i,j)。
因此這裏用到一個三重循環,時間複雜度O(n^3)。
附上代碼:
#include<stdio.h>
#include<string.h>
const char line1[21][4] = { "A1","A2","A3","A4", "A5","A6", "A7","A8", "A9","T1", "A10","A11", "A12","A13", "T2","A14", "A15","A16", "A17","A18","A1" };
const char line2[17][4] = {"B1","B2","B3","B4", "B5","T1", "B6","B7", "B8","B9", "B10","T2", "B11","B12", "B13","B14", "B15"};
const char map[35][4] = { "A1","A2","A3","A4", "A5","A6", "A7","A8", "A9","T1", "A10","A11", "A12","A13", "T2","A14", "A15","A16", "A17","A18","B1","B2","B3","B4", "B5", "B6","B7", "B8","B9", "B10","B11","B12", "B13","B14", "B15" };
int dstn[35][35];
const int inf = 0x3f3f3f3f;
void creat_map()
{
int i, j, k;
for (i = 0; i < 35; i++)
{
for (j = 0; j < 35; j++)
{
dstn[i][j] = inf;
}
}
for (k = 0; k < 20; k++)
{
for (i = 0; strcmp(line1[k], map[i]) != 0; i++);
for (j = 0; strcmp(line1[k+1], map[j]) != 0; j++);
dstn[i][j] = 1;
dstn[j][i] = 1;
}
for (k = 0; k < 16; k++)
{
for (i = 0; strcmp(line2[k], map[i]) != 0; i++);
for (j = 0; strcmp(line2[k + 1], map[j]) != 0; j++);
dstn[i][j] = 1;
dstn[j][i] = 1;
}
for (k = 0; k < 35; k++)
{
for (i = 0; i < 35; i++)
{
for (j = 0; j < 35; j++)
{
if (dstn[i][k] + dstn[k][j] < dstn[i][j])
{
dstn[i][j] = dstn[i][k] + dstn[k][j];
}
}
}
}
}
void main()
{
int i, j;
char a[4], b[4];
creat_map();
while (scanf("%s%s", a, b) != EOF)
{
for (i = 0; strcmp(a,map[i]) != 0 && i < 35; i++);
for (j = 0; strcmp(b,map[j]) != 0 && j < 35; j++);
printf("%d\n", dstn[i][j] + 1);
}
}