【问题描述】

编写一个程序实现北京地铁最短乘坐(站)线路查询,输入为起始站名和目的站名,输出为从起始站到目的站的最短乘坐站换乘线路。注:1. 要求采用Dijkstra算法实现;2)本题在实际测试时对数据文件进行了调整,使得输入的两站间只有一条最短路径。

【输入形式】

文件bgstations.txt为数据文件(可从课程网站中课程信息处下载),包含了北京地铁的线路及车站信息。其格式如下:

<地铁线路总条数>

<线路1> <线路1站数>

<站名1> <换乘状态>

<站名2> <换乘状态>

...

<线路2> <线路2站数>

<站名1> <换乘状态>

<站名2> <换乘状态>

...

说明:文件第一行为地铁总线路数;第二行第一个数为某条地铁线线号(如,1为1号线),第二个数为该条地铁线的总站数(如1号线共有23站),两数之间由一个空格分隔;第三行两个数据分别为地铁站名及换乘状态(0为非换乘站,1为换乘站),两数据间由一个空格分隔;以下同,依次为该线地铁其它站信息。在一条线路信息之后是下条地铁线路信息,格式相同。若某条地铁线为环线,则首站与末站信息相同(如北京地铁2号线,首站信息“西直门 1” ,末站信息为“西直门 1”)。例如本题提供的bgstations.txt文件(可从课程网站中课程信息处下载)内容如下:

12

1 23

苹果园 0

古城 0

八角游乐园 0

八宝山 0

玉泉路 0

五棵松 0

万寿路 0

公主坟 1

军事博物馆 1

木樨地 0

南礼士路 0

复兴门 1

西单 1

...

2 19

西直门 1

积水潭 0

鼓楼大街 1

...

西直门 1

...

该文件表明当前北京地铁共有12条线路(不含郊区线路),接着为每条线路信息。

打开当前目录下文件bgstations.txt,读入地铁线路信息,并从标准输入中读入起始站和目的站名(均为字符串,各占一行)。

【输出形式】

输出从起始站到目的站的乘坐信息,要求乘坐站数最少。换乘信息格式如下:

SSN-n1(m1)-S1-n2(m2)-...-ESN

其中:SSN和ESN分别为起始站名和目的站名;n为乘坐的地铁线路号,m为乘坐站数。
【样例输入】

西土城

北京西站

【样例输出】

西土城-10(1)-知春路-13(2)-西直门-4(2)-国家图书馆-9(4)-北京西站

【样例说明】

打开文件bgstations.txt,读入地铁线路信息,并从标准输入中读入查询起始站名为“西土城”,目的站名为“北京西站”。程序运行结果两站间最少乘坐站数的乘坐方式为“西土城站乘坐10号线1站至知春路站换乘13号线乘坐2站至西直门站换乘4号线乘坐2站至国家图书馆站换乘9号线乘坐4站至北京西站”。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MAXSTRLEN 41
#define INF 0x3f3f3f3f
#define MAXSTATNUM 500typedef struct _Edge
{int adjseq;int weight;int lineseq;struct _Edge *next;
} Edge;typedef struct _Station
{char name[MAXSTRLEN];int trans;int lineseq;int statseq;Edge *link;
} Station;typedef struct _Line
{int size;int seq;int isloop;struct _Station *list;
} Line;typedef struct _Railway
{int size;struct _Station list[MAXSTATNUM];
} Railway;void insert_Edge(Station *head, int end, int lineseq)
{Edge *rear = head->link;Edge *newEdge = (Edge *)malloc(sizeof(Edge));if (newEdge == NULL) {printf("allocation failure");exit(1);}newEdge->weight = 1;newEdge->lineseq = lineseq;newEdge->adjseq = end;newEdge->next = NULL;if (rear == NULL){head->link = newEdge;}else{while (rear->next != NULL) rear = rear->next; // reach the rearrear->next = newEdge;                        // add the new Edge at the rear}
}void input_Station(Railway *railway, Line line, int seq_inline, int seq_inrail)
{// input a station in a processed line to a railway system, and in this case seq_inrail == railway->sizestrcpy(railway->list[seq_inrail].name, line.list[seq_inline].name);railway->list[seq_inrail].trans = line.list[seq_inline].trans;railway->list[seq_inrail].lineseq = line.seq;railway->list[seq_inrail].statseq = seq_inrail;railway->list[seq_inrail].link = NULL;railway->size++;if (seq_inline == 0){// the first stationif (line.isloop){// the line is a loop, with the same station as start and endinsert_Edge(&(railway->list[seq_inrail]), line.list[1].statseq, line.seq);insert_Edge(&(railway->list[seq_inrail]), line.list[line.size - 2].statseq, line.seq);}else{// the start station in a non-loop has no previous stationinsert_Edge(&(railway->list[seq_inrail]), line.list[1].statseq, line.seq);}}else if (seq_inline == line.size - 1 - line.isloop){// the last stationif (line.isloop){// the line is a loop, with the same station as start and endinsert_Edge(&(railway->list[seq_inrail]), line.list[0].statseq, line.seq);insert_Edge(&(railway->list[seq_inrail]), line.list[line.size - 3].statseq, line.seq);}else{// the last station in a non-loop has no following stationinsert_Edge(&(railway->list[seq_inrail]), line.list[line.size - 2].statseq, line.seq);}}else{insert_Edge(&(railway->list[seq_inrail]), line.list[seq_inline + 1].statseq, line.seq);insert_Edge(&(railway->list[seq_inrail]), line.list[seq_inline - 1].statseq, line.seq);}
}void update_Station(Railway *railway, Line line, int seq_inline, int seq_inrail)
{// update a station's edges in a railway systemif (seq_inline == 0){// the first stationif (line.isloop){// the line is a loop, with the same station as start and endinsert_Edge(&(railway->list[seq_inrail]), line.list[1].statseq, line.seq);insert_Edge(&(railway->list[seq_inrail]), line.list[line.size - 2].statseq, line.seq);}else{// the start station in a non-loop has no previous stationinsert_Edge(&(railway->list[seq_inrail]), line.list[1].statseq, line.seq);}}else if (seq_inline == line.size - 1 - line.isloop){// the last stationif (line.isloop){// the line is a loop, with the same station as start and endinsert_Edge(&(railway->list[seq_inrail]), line.list[0].statseq, line.seq);insert_Edge(&(railway->list[seq_inrail]), line.list[line.size - 3].statseq, line.seq);}else{// the last station in a non-loop has no following stationinsert_Edge(&(railway->list[seq_inrail]), line.list[line.size - 2].statseq, line.seq);}}else{insert_Edge(&(railway->list[seq_inrail]), line.list[seq_inline + 1].statseq, line.seq);insert_Edge(&(railway->list[seq_inrail]), line.list[seq_inline - 1].statseq, line.seq);}
}int in_Rail(Railway railway, char name[])
{// find the station and return its sequence number in railsystemsint iter_rail;for (iter_rail = 0; iter_rail < railway.size; iter_rail++){if (strcmp(railway.list[iter_rail].name, name) == 0)return iter_rail;}return -1; // not found
}void input_Line(Railway *railway, Line line)
{// inputting a processed line into a railway systemint seq_inline, seq_inrail;if (railway->size == 0) // empty system{// initialize a railway systemfor (seq_inline = 0; seq_inline < line.size; seq_inline++){// in an empty railway system, the inline seq equals the inrail seqrailway->list[seq_inline].link = NULL;input_Station(railway, line, seq_inline, seq_inline);}}else{int seq_fromsize = railway->size;for (seq_inline = 0; seq_inline < line.size - line.isloop; seq_inline++){seq_inrail = in_Rail(*railway, line.list[seq_inline].name);if (seq_inrail != -1){// this station already exists in the railway systemupdate_Station(railway, line, seq_inline, seq_inrail);}else{// this is a new stationinput_Station(railway, line, seq_inline, seq_fromsize);seq_fromsize++;}}}
}void process_Line(Railway *railway, Line *line)
{// pre-process the statseq of the stations in a line (for the inputting of stations)int seq_inline, seq_inrail;if (railway->list == NULL){// empty railway systemfor (seq_inline = 0; seq_inline < line->size; seq_inline++)line->list[seq_inline].statseq = seq_inline;}else{int seq_fromsize = railway->size;for (seq_inline = 0; seq_inline < line->size; seq_inline++){seq_inrail = in_Rail(*railway, line->list[seq_inline].name);if (seq_inrail != -1){// this station already exists in the railway systemline->list[seq_inline].statseq = seq_inrail;}else{// new stationline->list[seq_inline].statseq = seq_fromsize;seq_fromsize++;}}}
}void Dijkstra(Railway *railway, char startname[], char destname[], int path[])
{int start = in_Rail(*railway,startname);int dest = in_Rail(*railway, destname);int *dist = (int *)malloc(railway->size*sizeof(int)); // dist[] stores the minimum distance from start to the indexed station// 0 means this station has been enclosedmemset(dist, INF, railway->size*sizeof(int));dist[start] = 0;Edge *link = railway->list[start].link;while (link != NULL){dist[link->adjseq] = link->weight;path[link->adjseq] = start;link = link->next;}while (dist[dest] == INF){int min = INF, minstat = dest, iter;for (iter = 0; iter < railway->size; iter++){if (dist[iter] != 0 && dist[iter] < min){// not enclosed, and find the minimummin = dist[iter];minstat = iter;}}link = railway->list[minstat].link;if (link == NULL) exit(1);while (link != NULL){if (dist[minstat] + link->weight < dist[link->adjseq]){dist[link->adjseq] = dist[minstat] + link->weight;path[link->adjseq] = minstat;}link = link->next;}dist[minstat] = 0;}free(dist);/* just for debuggingwhile (dest != start){printf("%s<-",railway->list[dest].name);dest = path[dest];}printf("%s\n", railway->list[start].name);*/
}int get_Lineseq(Railway railway, int stat1, int stat2)
{Edge *link = railway.list[stat1].link;while (link != NULL){if (link->adjseq == stat2)return link->lineseq;link = link->next;}return -1; // not connected
}void depict_Path(Railway *railway, int start, int dest, int path[])
{int *track = (int *)malloc(railway->size*sizeof(int));memset(track, INF, railway->size*sizeof(int));int iter = 0;while (dest != start){track[iter++] = dest;dest = path[dest];}track[iter] = start;int i = 0, j = iter;while (i < j){// reverse track[]int tmp;tmp = track[j];track[j] = track[i];track[i] = tmp;i++, j--;}/*for (i = 0; i <= iter; i++)printf("%s %d -", railway->list[track[i]].name, railway->list[track[i]].lineseq);*/int currstats = 1;printf("%s-",railway->list[track[0]].name);for (i = 1; i < iter; i++){if (   get_Lineseq(*railway, railway->list[track[i - 1]].statseq, railway->list[track[i]].statseq)!= get_Lineseq(*railway, railway->list[track[i + 1]].statseq, railway->list[track[i]].statseq)){// the previous station and the next one is not on the same line: transfering printf("%d(%d)-%s-", get_Lineseq(*railway, railway->list[track[i - 1]].statseq, railway->list[track[i]].statseq), currstats, railway->list[track[i]].name);currstats = 1;}else{currstats++;}}printf("%d(%d)-%s\n", get_Lineseq(*railway, railway->list[track[i - 1]].statseq, railway->list[track[i]].statseq), currstats, railway->list[track[iter]].name);
}int main()
{FILE *fin;fin = fopen("bgstations.txt","r");if (fin == NULL) exit(1);int linenum, lineseq, statnum, trans;int i, j;char statname[MAXSTRLEN];Railway *beijing = (Railway *)malloc(sizeof(Railway));beijing->size = 0;Line *newline = (Line *)malloc(sizeof(Line));fscanf(fin,"%d\n",&linenum);for (i = 1; i <= linenum; i++){fscanf(fin, "%d %d\n",&lineseq, &statnum);newline->seq = lineseq;newline->size = statnum; newline->isloop = 0;newline->list = (Station *)malloc(statnum*sizeof(Station));for (j = 0; j < statnum; j++){fscanf(fin, "%s %d\n", statname, &trans);newline->list[j].lineseq = i;strcpy(newline->list[j].name,statname);newline->list[j].trans = trans;}if (strcmp(newline->list[0].name, statname) == 0)newline->isloop = 1;process_Line(beijing, newline);input_Line(beijing, *newline);free(newline->list);fscanf(fin, "\n");}char startname[MAXSTRLEN], destname[MAXSTRLEN];scanf("%s",startname);scanf("%s",destname);int *path = (int *)malloc(beijing->size*sizeof(int));Dijkstra(beijing, startname, destname, path);depict_Path(beijing, in_Rail(*beijing, startname), in_Rail(*beijing, destname), path);/* just for debuggingfor (i = 0; i < beijing->size; i++){printf("%s %d %d\n", beijing->list[i].name, beijing->list[i].statseq, beijing->list[i].trans);Edge *curr = beijing->list[i].link;while (curr != NULL){printf("  %s %d %d\n", beijing->list[curr->adjseq].name, curr->adjseq, beijing->list[curr->adjseq].trans);curr = curr->next;}}*/free(newline);free(path);fclose(fin);return 0;
}

北京地铁乘坐路线查询相关推荐

  1. python地铁查询系统_基于图结构实现地铁乘坐线路查询

    基于图结构实现地铁乘坐线路查询 github-python算法和flaskapp部分:repo github-android部分:repo flaskapp接口文档:传送门 深度了解Dijkstra优 ...

  2. 基于图结构实现地铁乘坐线路查询

    基于图结构实现地铁乘坐线路查询 github-python算法和flaskapp部分:repo github-android部分:repo flaskapp接口文档:传送门 深度了解Dijkstra优 ...

  3. c++实现北京地铁线路查询系统

    //使用前将bgstations.txt(文件的内容在代码末尾)放在与cpp文件的同一位置 #include<stdio.h> #include<string.h> #incl ...

  4. 运用BFS算法实现北京地铁路线换乘系统

    本文通过我做过的一个小项目来分享一下如何通过BFS搜索算法实现北京地铁换乘路线.搜索的规则分别为最短距离与最少换乘线路.BFS算法的原理这里就不讲了,推荐一个B站的视频,对搜索算法讲解的很清晰: BF ...

  5. QT地铁路线查询项目(四)

    1,项目基本介绍 该项目主要是实现了广州地铁的路线查询,地铁站点数据主要是yin项目开发框架采用了QT 框架,采用了C++开发语言,项目界面比较简单,主要应用了QT的一些基本的UI控件,核心基础主要是 ...

  6. 北京地铁票价查询系统 c++ Dijkstra算法

    包含一号线.二号线全部,还有两小段 数据来自北京地铁官网 资源链接 https://download.csdn.net/download/renzemingcsdn/44352688 #include ...

  7. 软件工程结对项目——地铁出行路线规划程序

    GitHub链接:https://github.com/2016bits/subway PSP2.1表格 PSP2.1 Personal Software Process Stages 预计耗时(分钟 ...

  8. 双向广搜的DIJKSTRA算法--简易的北京地铁导航实现

    本学期的课程设计,实现最短路的算法,于是采用了DIJKSTRA算法,并用双向广搜优化了. 实现了简易的北京地铁导航.于是把代码分享出来. (核心代码是find_min(),Dijkstra()部分) ...

  9. WPF简易北京地铁效果图

    这个是百度地图上北京地铁的地址http://map.baidu.com/?subwayShareId=beijing,131,我们先看下百度上面的效果图 我要实现的内容比较简单,就是绘制这些图,和在地 ...

  10. 北京地铁月度消费总金额计算(Python版)

    最近业余时间在学习Python,这是那天坐地铁时突发奇想,想看看我这一个月的地铁费共多少钱,所以简单的构思了下思路,就直接开写了,没想到用Python来实现还挺简单的. 设计思路: 每次乘车正常消费7 ...

最新文章

  1. 一场由金山词霸引起的车祸 Process finished with exit code -1073741819 (0xC0000005)
  2. 访问权限的等级最大到最小依次是:
  3. Docker安装mysql容器
  4. Spring Boot 2发送邮件手把手图文教程
  5. 1.0 MySQL数据库基础知识
  6. yum 安装报Header V3 DSA signature: NOKEY 的错
  7. 洛谷 P1352 没有上司的舞会【树形DP/邻接链表+链式前向星】
  8. 如何使frame能居中显示
  9. 联想X61-Xp系统重装Ubuntu21.10
  10. 万年历代码java功能_java 的万年历代码
  11. Web前端-HTML基础
  12. java生成word并导出pdf
  13. postman接口导入
  14. 算法学习之投票算法以及对应leetcode题目
  15. adb 备份和还原apk应用数据
  16. c语言中scanf(%d%*c, n);的意思
  17. kubeadm部署kubernetes集群
  18. Oracle11g下载地址Oracle下载
  19. 百度服务器保存信息多久,百度快照在百度服务器里保存多长时间???
  20. Trx-address和交易的address

热门文章

  1. int为什么是-32768到32767
  2. 大规模海量并发难题的本质
  3. 课程设计:波形发生器
  4. android 格式化sd咔_在Android手机上怎么对SD卡进行格式化
  5. 快速使用ros小乌龟教程——ROS初体验
  6. 数据分析 | 全距和四分位距分别是什么
  7. Android-手撸抖音“潜艇大挑战”,非科班面试之旅
  8. Android Studio Gradle build daemon disappeared unexpectedly
  9. Spinnaker第七节—Orca代码详解
  10. 无线信道仿真 matlab,基于Matlab的无线信道仿真.doc