北京地铁线路查询

Dijkstra Algorithm 迪杰斯特拉算法

北京地铁线路查询是对最短路径算法的应用,此代码运用迪杰斯特拉算法求出两站之间的一条最短路径
如果读者想要求出所有的最短路径,可参考弗洛伊德算法

【问题描述】编写一个程序实现北京地铁最短乘坐(站)线路查询,输入为起始站名和目的站名,输出为从起始站到目的站的最短乘坐站换乘线路。注: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. 初始化图,将所有的线路连接成图。方法是:将每一站作为顶点,即图的顶点,存成结构体。结构体的内容为:
    1. 站的名称
    2. 是否为换乘站
    将两个线路的连线(距离),也就是图的边同样作为结构体存储。结构体的内容为:
    3. 站与站间的距离
    4. 两个站所在的线路号
    随后我们初始化图。

    一维数组BGvertex用来存储每一个顶点,数组下标即为顶点的编号。二维数组BGweights存储图的边,是无向图的邻接矩阵。对于每一个站,首先我们判断它是否为换乘站,如果不是,则将它存储到BGvertex中并返回数组下标(这个顶点的编号),将v2赋值给v1(作用是将此顶点作为下一个顶点的起始点),并继续扫描顶点。如果是换乘站,则在BGvertex中寻找这个换乘站,如果没找到,则按照非换乘站处理,如果找到,则直接返回它的下标(顶点编号)。这样我们遍得到了北京地铁站的无向图。

    这里需要注意的是,在得到图之后,我们需要对图进行“初始化”,即将两顶点之间没有边的邻接矩阵的wei初始化为INFINITY(无穷大),将两个顶点不在任意一条线路的邻接矩阵的ino初始化为-1,进而方便后续迪杰斯特拉算法的运行。

  2. 迪杰斯特拉算法
    本代码在原算法的基础上,只增加了当找到对应顶点后跳出的步骤。如果读者对迪杰斯特拉算法不了解,可先自行学习,这里不再阐述。

  3. 按格式输出
    我们通过回溯spath的方式(spath记录的是每一个顶点的前驱,详细请见迪杰斯特拉算法),并将线路中的每一个地铁站倒序存进数组board中。我们首先存入头站点,随后循环输出其余站点。在循环中需要判断是否换乘。我们将每一次循环的字符串strcat连接到path的尾部,最后输出。

详细代码如下

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXNUM 512 //地铁最大站数
#define MAXLEN 16
#define INFINITY 32767

struct station
{
   
    char sname[MAXLEN];
    int ischange; //是否为换乘站,0为不是换乘站,1为是换乘站
};

struct weight
{
   
    int wei; //两个站之间的权重,即相差的站数
    int ino //两个顶点所在的线号
};

struct station BGvertex[MAXNUM]; //地铁网的顶点
struct weight BGweights[MAXNUM][MAXNUM]; //网络图权重
int Vnum = 0
  • 12
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值