【问题描述】
编写一个程序实现北京地铁最短乘坐(站)线路查询,输入为起始站名和目的站名,输出为从起始站到目的站的最短乘坐站换乘线路。注: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)-北京西站
(或西土城-10(1)-知春路-13(2)-西直门-2(1)-车公庄-6(2)-白石桥南-9(3)-北京西站)
【样例说明】
打开文件bgstations.txt,读入地铁线路信息,并从标准输入中读入查询起始站名为“西土城”,目的站名为“北京西站”。程序运行结果两站间最少乘坐站数的乘坐方式为“西土城站乘坐10号线1站至知春路站换乘13号线乘坐2站至西直门站换乘4号线乘坐2站至国家图书馆站换乘9号线乘坐4站至北京西站”。本样例存在两条最少站数的乘坐方式,只要找出一条就可以。
【题解】
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 5 #define MAXNUM 512 6 #define MAXLEN 16 7 #define INFINITY 32767 8 9 typedef struct Station 10 { 11 char StopName[MAXLEN]; 12 int ischange; 13 }Station; 14 typedef struct Weight 15 { 16 int wei; 17 int LineNo; 18 }Weight; 19 20 Station BGvertex[MAXNUM]; 21 Weight BGweights[MAXNUM][MAXNUM]; 22 int Vnum=0; 23 24 void initMap(void); 25 int addVertex(Station st); 26 void Dijkstra(int v0,int v1,int spath[]); 27 void printPath(int v0,int v1,int spath[]); 28 29 int main(void) 30 { 31 int v1,v2,spath[1000]; 32 int i,j; 33 char start[MAXLEN],end[MAXLEN]; 34 35 for(i=0;i<MAXNUM;i++) 36 for(j=0;j<MAXNUM;j++) 37 { 38 BGweights[i][j].wei=INFINITY; 39 BGweights[i][j].LineNo=0; 40 } 41 42 initMap(); 43 scanf("%s%s",start,end); 44 45 v1=v2=-1; 46 for(i=0;i<Vnum;i++) 47 if(!strcmp(BGvertex[i].StopName,start)) 48 { 49 v1=i; 50 break; 51 } 52 for(i=0;i<Vnum;i++) 53 if(!strcmp(BGvertex[i].StopName,end)) 54 { 55 v2=i; 56 break; 57 } 58 59 Dijkstra(v1,v2,spath); 60 printPath(v1,v2,spath); 61 62 return 0; 63 } 64 void initMap(void) 65 { 66 FILE *fp; 67 int i,j,snum,lno,lnum,v1,v2; 68 Station st; 69 70 if((fp=fopen("bgstations.txt","r"))==NULL) 71 exit(-1); 72 73 fscanf(fp,"%d",&snum); 74 for(i=0;i<snum;i++) 75 { 76 fscanf(fp,"%d %d",&lno,&lnum); 77 v1=v2=-1; 78 for(j=0;j<lnum;j++) 79 { 80 fscanf(fp,"%s %d",st.StopName,&st.ischange); 81 v2=addVertex(st); 82 if(v1!=-1) 83 { 84 BGweights[v1][v2].wei=BGweights[v2][v1].wei=1; 85 BGweights[v1][v2].LineNo=BGweights[v2][v1].LineNo=lno; 86 } 87 v1=v2; 88 } 89 } 90 fclose(fp); 91 return; 92 } 93 int addVertex(Station st) 94 { 95 int i; 96 97 for(i=0;i<Vnum;i++) 98 if(!strcmp(BGvertex[i].StopName,st.StopName)) 99 return i; 100 101 BGvertex[i]=st; 102 return Vnum++; 103 } 104 void Dijkstra(int v0,int v1,int spath[]) 105 { 106 int i,j,v,minweight; 107 int wfound[MAXNUM]={0}; 108 int sweight[MAXNUM]={0}; 109 for(i=0;i<Vnum;i++) 110 { 111 sweight[i]=BGweights[v0][i].wei; 112 spath[i]=v0; 113 } 114 sweight[v0]=0; 115 wfound[v0]=1; 116 117 v=-1; 118 for(i=0,j=0;i<Vnum-1;i++) 119 { 120 minweight=INFINITY; 121 for(j=0;j<Vnum;j++) 122 if(!wfound[j] && sweight[j]<minweight) 123 { 124 v=j; 125 minweight=sweight[v]; 126 } 127 wfound[v]=1; 128 if(v==v1) 129 return; 130 for(j=0;j<Vnum;j++) 131 if(!wfound[j] && BGweights[v][j].LineNo>0 && minweight+BGweights[v][j].wei<sweight[j]) 132 { 133 sweight[j]=minweight+BGweights[v][j].wei; 134 spath[j]=v; 135 } 136 } 137 for(i=0;i<j;i++) 138 printf("%d ",spath[i]); 139 return; 140 } 141 void printPath(int v0,int v1,int spath[]) 142 { 143 char path[80]={0},buf[80]; 144 int board[80],bcount=0,line=-1,sc=0; 145 int i; 146 do 147 { 148 board[bcount++]=v1; 149 }while((v1=spath[v1])!=v0); 150 board[bcount++]=v0; 151 152 line=BGweights[board[bcount-1]][board[bcount-2]].LineNo; 153 sprintf(buf,"%s-%d(",BGvertex[board[bcount-1]].StopName,line); 154 strcpy(path,buf); 155 sc=1; 156 for(i=bcount-2;i>0;i--,sc++) 157 if(BGweights[board[i]][board[i-1]].LineNo!=line) 158 { 159 line=BGweights[board[i]][board[i-1]].LineNo; 160 sprintf(buf,"%d)-%s-%d(",sc,BGvertex[board[i]].StopName,line); 161 strcat(path,buf); 162 sc=0; 163 } 164 sprintf(buf,"%d)-%s\n",sc,BGvertex[board[i]].StopName); 165 strcat(path,buf); 166 puts(path); 167 168 return; 169 }
原文地址:https://www.cnblogs.com/tuoniao/p/10346421.html