【问题描述】
编写一个程序实现北京地铁最短乘坐(站)线路查询,输入为起始站名和目的站名,输出为从起始站到目的站的最短乘坐站换乘线路。注:1. 要求采用Dijkstra算法实现;2)如果两站间存在多条最短路径,找出其中的一条就行。
【输入形式】
文件bgstations.txt为数据文件(可从课程网站中课程信息处下载),包含了北京地铁的线路及车站信息。其格式如下:
<地铁线路总条数>
<线路1> <线路1站数>
<站名1> <换乘状态>
<站名2> <换乘状态>
…
<线路2> <线路2站数>
<站名1> <换乘状态>
<站名2> <换乘状态>
…
说明:文件第一行为地铁总线路数;第二行第一个数为某条地铁线线号(如,1为1号线),第二个数为该条地铁线的总站数(如1号线共有23站),两数之间由一个空格分隔;第三行两个数据分别为地铁站名及换乘状态(0为非换乘站,1为换乘站),两数据间由一个空格分隔;以下同,依次为该线地铁其它站信息。在一条线路信息之后是下条地铁线路信息,格式相同。若某条地铁线为环线,则首站与末站信息相同(如北京地铁2号线,首站信息“西直门 1” ,末站信息为“西直门 1”)。例如本题提供的bgstations.txt文件(可从课程网站中课程信息处下载)内容如下:
13
1 23
苹果园 0
古城 0
八角游乐园 0
八宝山 0
玉泉路 0
五棵松 0
万寿路 0
公主坟 1
军事博物馆 1
木樨地 0
南礼士路 0
复兴门 1
西单 1
…
2 19
西直门 1
积水潭 0
鼓楼大街 1
…
西直门 1
…
该文件表明当前北京地铁共有13条线路(不含郊区线路),接着为每条线路信息。
打开当前目录下文件bgstations.txt,读入地铁线路信息,并从标准输入中读入起始站和目的站名(均为字符串,各占一行)。
【输出形式】
输出从起始站到目的站的乘坐信息,要求乘坐站数最少。换乘信息格式如下:
SSN-n1(m1)-S1-n2(m2)-…-ESN
其中:SSN和ESN分别为起始站名和目的站名;n为乘坐的地铁线路号,m为乘坐站数。
【样例输入】
西土城
北京西站
【样例输出】
西土城-10(1)-知春路-13(2)-西直门-4(2)-国家图书馆-9(4)-北京西站
(或西土城-10(1)-知春路-13(2)-西直门-2(1)-车公庄-6(2)-白石桥南-9(3)-北京西站)
【样例说明】
打开文件bgstations.txt,读入地铁线路信息,并从标准输入中读入查询起始站名为“西土城”,目的站名为“北京西站”。程序运行结果两站间最少乘坐站数的乘坐方式为“西土城站乘坐10号线1站至知春路站换乘13号线乘坐2站至西直门站换乘4号线乘坐2站至国家图书馆站换乘9号线乘坐4站至北京西站”。本样例存在两条最少站数的乘坐方式,只要找出一条就可以。
代码1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 1005
int n, a[15], k = 0, tot = 0, head[N];
char s[25], s1[25], s2[25], name[N][25];
struct NODE
{
int from, to, next, id;
} e[N];
int find(char s[])
{
int i;
int t = -1;
for (i = 1; i <= tot; i++)
if (strcmp(s, name[i]) == 0)
{
t = i;
break;
}
return t;
}
void add(int x, int y, int z)
{
e[++k].to = y;
e[k].next = head[x];
e[k].id = z;
e[k].from = x;
head[x] = k;
}
int d[N], q[N * 10], v[N], from[N], ans[N];
void spfa(int xx, int yy)
{
int i;
for (i = 1; i <= tot; i++)
d[i] = 100000;
d[xx] = 0;
q[1] = xx;
v[xx] = 1;
int l = 1, r = 1;
while (l <= r)
{
int x = q[l++];
v[x] = 0;
i = head[x];
while (i)
{
if (d[e[i].to] > d[x] + 1)
{
d[e[i].to] = d[x] + 1;
from[e[i].to] = i;
if (!v[e[i].to])
{
v[e[i].to] = 1;
q[++r] = e[i].to;
}
}
i = e[i].next;
}
}
tot = 0;
while (yy != xx)
{
ans[++tot] = from[yy];
yy = e[from[yy]].from;
}
printf("%s", name[xx]);
int num = 0;
for (i = tot; i >= 1; i--)
{
if (i != tot && e[ans[i]].id != e[ans[i + 1]].id)
{
printf("-%d(%d)-%s", e[ans[i + 1]].id, num, name[e[ans[i]].from]);
num = 1;
}
else
num++;
}
printf("-%d(%d)-%s\n", e[ans[1]].id, num, name[e[ans[1]].to]);
}
int main()
{
FILE *fp = fopen("bgstations.txt", "r");
fscanf(fp, "%d", &n);
int i, j, x, y;
for (i = 1; i <= n; i++)
{
fscanf(fp, "%d%d", &x, &a[i]);
int pre = -1;
for (j = 1; j <= a[i]; j++)
{
fscanf(fp, "%s%d", &s, &y);
int t = find(s);
if (t == -1)
{
t = ++tot;
strcpy(name[tot], s);
}
if (pre != -1)
{
add(pre, t