网上看的一道题,自己用C++实现了一下,如有错误欢迎指正
#include <string>
#include <iostream>
using namespace std;
/************************************************************************/
/*地铁换乘
描述:已知2条地铁线路,其中A为环线,B为东西向线路,线路都是双向的。经过的站点名分别如下,
两条线交叉的换乘点用T1、T2表示。编写程序,任意输入两个站点名称,输出乘坐地铁最少需要经过的
车站数量(含输入的起点和终点,换乘站点只计算一次)。
地铁线A(环线)经过车站:A1 A2 A3 A4 A5 A6 A7 A8 A9 T1 A10 A11 A12 A13 T2 A14 A15 A16 A17 A18
地铁线B(直线)经过车站:B1 B2 B3 B4 B5 T1 B6 B7 B8 B9 B10 T2 B11 B12 B13 B14 B15
输入:输入两个不同的站名
输出:输出最少经过的站数,含输入的起点和终点,换乘站点只计算一次
输入样例:A1 A3
输出样例:3 */
/************************************************************************/
#define NODENUM 50
#define MAXWEIGHT 65535
typedef struct Node
{
bool flag;
int weight;
}Matrix[NODENUM][NODENUM];
typedef struct MGraph
{
int arcnum;
int vertexnum;
Matrix adjmatrix;
}MGraph,*pMGraph;
typedef enum index{A1,A2,A3,A4,A5,A6,A7,A8,A9,T1,A10,A11,A12,A13,T2,A14,A15,A16,A17,A18,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12,B13,B14,B15};
string str[]={"A1","A2","A3","A4","A5","A6","A7","A8","A9","T1","A10","A11","A12","A13","T2",
"A14","A15","A16","A17","A18","B1","B2","B3","B4","B5","B6","B7","B8","B9","B10","B11","B12","B13","B14","B15"};
void CreateSubRailWay(pMGraph &mg)//n为站点的个数
{
int n=sizeof(str)/sizeof(string);
mg->vertexnum=n;
for (int i=0;i<n;i++)
{
for (int j=0;j<n;j++)
{
mg->adjmatrix[i][j].weight=MAXWEIGHT;
}
}
//对相邻的站点的权值进行赋值
for (int i=A1;i<=A17;i++)//对环形路线进行赋值
{
mg->adjmatrix[i][(i+1)].weight=1;
mg->adjmatrix[i+1][i].weight=1;
}
mg->adjmatrix[A18][A1].weight=1;
mg->adjmatrix[A1][A18].weight=1;
//对直线线路进行赋值
for (int i=B1;i<=B4;i++)
{
mg->adjmatrix[i][i+1].weight=1;
mg->adjmatrix[i+1][i].weight=1;
}
//B5T1 B6T1
mg->adjmatrix[B5][T1].weight=1;
mg->adjmatrix[T1][B5].weight=1;
mg->adjmatrix[T1][B6].weight=1;
mg->adjmatrix[B6][T1].weight=1;
for (int i=B6;i<=B9;i++)
{
mg->adjmatrix[i][i+1].weight=1;
mg->adjmatrix[i+1][i].weight=1;
}
//B10T2 B11T2
mg->adjmatrix[B10][T2].weight=1;
mg->adjmatrix[T2][B10].weight=1;
mg->adjmatrix[T2][B11].weight=1;
mg->adjmatrix[B11][T2].weight=1;
for (int i=B11;i<=B14;i++)
{
mg->adjmatrix[i][i+1].weight=1;
mg->adjmatrix[i+1][i].weight=1;
}
//查看矩阵是否正确(可注释掉)
for (int k=0;k<n;k++)
{
for (int m=0;m<n;m++)
{
if (mg->adjmatrix[k][m].weight==MAXWEIGHT)
{
printf("%d ",0);
}
else
{
printf("%d ",mg->adjmatrix[k][m].weight);
}
}
printf("\n");
}
}
//使用Dijk算法求最短路径
int Path[NODENUM];//存放前一个结点
int ShortestPath[NODENUM];
bool used_dij[NODENUM];//表示已经求得最短路径的结点
int Dijk(pMGraph &mg,int startpos)
{
//首先进行初始化
int n=mg->vertexnum;
for (int i=0;i<n;i++)
{
Path[i]=startpos;
ShortestPath[i]=mg->adjmatrix[startpos][i].weight;
used_dij[i]=false;
}
//对起始结点初始化
ShortestPath[startpos]=0;
used_dij[startpos]=true;
Path[startpos]=startpos;
for (int i=1;i<n;i++)//进行n-1次遍历
{
int min=MAXWEIGHT;
int k;
//先找出当前权值最小的点
for (int j=0;j<n;j++)
{
if (used_dij[j]!=true && min>ShortestPath[j])
{
min=ShortestPath[j];
k=j;
}
}
//对最小点操作
used_dij[k]=true;
//更新
for (int j=0;j<n;j++)
{
if (used_dij[j]==false && mg->adjmatrix[k][j].weight+min<ShortestPath[j])
{
ShortestPath[j]=min+mg->adjmatrix[k][j].weight;
Path[j]=k;//记录它的前一个结点
}
}
}
return 0;
}
int main(int argc,char *argv[])
{
pMGraph mg=new MGraph;
CreateSubRailWay(mg);
printf("请输入起点和终点,空格分隔\n");
string start,end;
cin>>start;
cin>>end;
//根据输入的站点寻找站点的索引
int startpos,endpos;
for (int i=0;i<sizeof(str)/sizeof(string);i++)
{
if (start==str[i])
{
startpos=i;
}
if (end==str[i])
{
endpos=i;
}
}
Dijk(mg,startpos);
//根据Dijk输出的最短路径和前一节点数组确定路径长度和路径经过的各点
printf("最短路径经过的总的站点个数为:%d\n",ShortestPath[endpos]+1);
int len=sizeof(str)/sizeof(string);
int sitecount=0;
int sites[sizeof(str)/sizeof(string)];
//经过的站点顺序为
int now=endpos;
while(now!=startpos)
{
sites[sitecount++]=now;
now=Path[now];
}
sites[sitecount]=now;
//进行逆序输出
printf("经过的站点顺序依次是:");
for(int i=0;i<=sitecount;i++)
{
cout<<str[sites[sitecount-i]]<<"->";
}
cout<<"end"<<endl;
}