BUAA北京地铁乘坐线路查询

【问题描述】

编写一个程序实现北京地铁最短乘坐(站)线路查询,输入为起始站名和目的站名,输出为从起始站到目的站的最短乘坐站换乘线路。注: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
  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值