#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<string>
#include<fstream>
#include<windows.h>
#define NumVertices 405
#define INFINITY 65535 //设65535为无穷大
using namespace std;
typedef int EdgeDate;
typedef int Pathmatrix[NumVertices][NumVertices];
typedef int ShortPathTable[NumVertices][NumVertices];
typedef struct
{
char name[50];//站点名
int linenum[5];//线路对应序列
}station;
typedef struct
{
char linename[20];//线路名称
}linesystem;
typedef struct
{
linesystem line[15];
station VerList[NumVertices];//站点信息
EdgeDate Edge[NumVertices][NumVertices]; // 距离边权值
int n,e;
}MTGraph;
void SetLine(MTGraph &G)//初始化站点所在线路对应的序列
{
/*
605路 1
615路 2
402路 3
368外环 4
368内环 5
400外环 6
400快内环 7
973路 8
135路 9
26路 10
300快外环 11
94路 12
34路 13
200外环 14
671路 15
*/
int i;
G.VerList[0].linenum[0] = 3; G.VerList[0].linenum[1] = 4; G.VerList[0].linenum[2] = 5; G.VerList[0].linenum[3] = 11; G.VerList[0].linenum[4] = 15;
G.VerList[1].linenum[0] = 3; G.VerList[1].linenum[1] = 4; G.VerList[1].linenum[2] = 5; G.VerList[1].linenum[3] = 11; G.VerList[1].linenum[4] = 3;
G.VerList[2].linenum[0] = 4; G.VerList[2].linenum[1] = 5; G.VerList[2].linenum[2] = 8; G.VerList[2].linenum[3] = 11; G.VerList[2].linenum[4] = 4;
G.VerList[3].linenum[0] = 4; G.VerList[3].linenum[1] = 5; G.VerList[3].linenum[2] = 8; G.VerList[3].linenum[3] = 11; G.VerList[3].linenum[4] = 4;
//15
for(i=391;i<=404;i++){
G.VerList[i].linenum[0]=15;G.VerList[i].linenum[1]=15;G.VerList[i].linenum[2]=15;G.VerList[i].linenum[3]=15;G.VerList[i].linenum[4]=15;
}
}
void Getline(MTGraph &G) //读入线路 名称
{
int i=0;
ifstream ifp;
ifp.open("bus_Rname.txt",ios::in);
while(!ifp.eof()) // 如果未读完,继续读文本 eof end of file
{
ifp>>G.line[i].linename; //
i++;
}
ifp.close();
}
void CreateGraph_2(MTGraph& G)//初始化一般时间段
{
Getline(G);
SetLine(G);//读入线路信息
int i;
G.n = 0;
G.e = 0;
int j = 0;
ifstream ifp;
ifp.open("bus_name.txt", ios::in);
while (!ifp.eof())
{
++G.n;
ifp >> G.VerList[j].name;//读入站点相关信息
j++;
}
ifp.close();
for (i = 0; i < G.n; i++)
{
for (j = 0; j < G.n; j++)
{
G.Edge[i][j] = INFINITY;//权值初始化
}
G.Edge[i][i] = 0;
}
int v1, v2, w;
FILE* fp2;
fp2=fopen("bus_time.txt", "r");
if (NULL == fp2) printf("文件打开失败");
else
{
while (!feof(fp2))
{
fscanf(fp2, "%d %d %d", &v1, &v2, &w);//读入边权值
G.Edge[v1][v2] = w;
G.Edge[v2][v1] = w;
++G.e;
}
fclose(fp2);
}
}
int Getnum(MTGraph& G, char* a)//取得站点对应下标
{
int i = 0;
while (i < G.n)
{
if (strcmp(G.VerList[i].name, a) == 0)
{
return i;
break;
}
else
i++;
}
if (i >= G.n)
return -1;
}
void ShortestPath(MTGraph &G,Pathmatrix P,ShortPathTable D)//求最短路径
{
int trans[118];
char a[20],b[20];
int i,j,v,w,k,m,n,p,q,r,t,T;
char s;
for(i=-1;i<118;i++)
{
trans[i]=i;//对比是否为换乘
}
for(v=0;v<G.n;v++)//初始化D与P
{
for(w=0;w<G.n;w++)
{
D[v][w]=G.Edge[v][w];//D值为对应权值
P[v][w]=w;//初始化P
}
}
for(k=0;k<G.n;k++)
{
for(v=0;v<G.n;v++)
{
for(w=0;w<G.n;w++)
{
if(D[v][w]>D[v][k]+D[k][w])//如果经过下标为k顶点路径比原两点间路径更短,将当前权值设为更小的
{
D[v][w]=D[v][k]+D[k][w];//
P[v][w]=P[v][k];//路径设置经过下标为k的顶点
}
}
}
}//Floyd算法求最小路径
while(1)
{
cout<<endl<<endl<<endl<<" ☆最快路径查询☆"<<endl;
cout<<".............................................................................."<<endl<<endl;
while(1)
{
while(1)
{
cout<<" >>>>>>>>>请输入起点站:";
cin>>a;
v=Getnum(G,a);
if(v==-1)
cout<<"站点不存在请重新输入!"<<endl;
else
break;
}
while(1)
{
cout<<endl<<" >>>>>>>>>请输入终点站:";
cin>>b;
w=Getnum(G,b);
if(w==-1)
cout<<"站点不存在请重新输入!"<<endl;
else
break;
}
if(v==w)
cout<<"请输入两个不同的站点名!"<<endl;
else
break;
}//输入起始点于终点
system("cls");
p=0;
k=P[v][w];
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
if(G.VerList[v].linenum[i]==G.VerList[k].linenum[j])
{p=G.VerList[v].linenum[i];}//确定初始时所在的地铁线路对应序列
}
}
if(p==0)
{p=G.VerList[v].linenum[0];}//如果不能找到对应序列则取下一结点的序列,仅针对13号起点终点与机场线起点这种3线交叉情况 */
cout<<endl<<endl<<endl<<" ☆最快路径查询☆"<<endl;
cout<<".............................................................................."<<endl<<endl;
cout<<"......................起点在"<<p<<".........."<<G.line[p-1].linename<<"........................"<<endl<<endl;
cout<<" >>>>>>>>>用时最短路径: "<<endl<<endl<<" >>>>>>>>> ->在 "<<G.VerList[v].name<<" 乘 "<<G.line[p-1].linename<<" ("<<G.VerList[k].name<<"方向)"<<endl;
m=v;//设m为k在最短路径中的直接前驱
r=v;
T=3;
while(k!=w)
{
q=-1;
while(k!=trans[q]&&k<118)
{
q++;
if(k==trans[q])//如果k满足是可换乘节点
{
n=P[k][w];//设m为k在最短路径中的直接后继
p=t=-1;
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
if(G.VerList[m].linenum[i]==G.VerList[k].linenum[j])
{p=G.VerList[m].linenum[i];}
}
}
if(p==-1)
p=G.VerList[m].linenum[0];
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
if(G.VerList[k].linenum[i]==G.VerList[n].linenum[j])
{t=G.VerList[k].linenum[i];}
}
}
if(t==-1)
{
/*if(k==9||k==12)
t=9;
else if(k==23)
t=13;
else */
t=G.VerList[n].linenum[1];
}
if(p!=t)//若k前后两线路序列号不同则换乘
{
int a=D[r][k];
double b=a/1000;
cout<<" >>>>>>>>> ->距离为"<<D[r][k]<<"米,用时约"<<b<<"分钟 至:"<<G.VerList[k].name<<" 换乘 "<<G.line[t-1].linename<<" ("<<G.VerList[n].name<<"方向)"<<endl;//若路径点为换乘点则打印
r=k;//设定r结点用于求分段时间
T+=5;
}
}
}
m=P[m][w];//m后移
k=P[k][w];//k后移
}
int c=D[r][w];
int f=D[v][w];
int value;
double d=c/1000;
double e=f/1000;
if(D[v][w]<6000)
value=3;
else if(6000<D[v][w]&&D[v][w]<12000)
value=4;
else if(12000<D[v][w]&&D[v][w]<22000)
value=5;
else if(22000<D[v][w]&&D[v][w]<32000)
value=6;
else if(52000<D[v][w]&&D[v][w]<72000)
value=7;
else if(72000<D[v][w]&&D[v][w]<92000)
value=8;
cout<<" >>>>>>>>> ->距离为"<<D[r][w]<<"米,用时约"<<d<<"分钟,到达终点:"<<G.VerList[w].name<<endl;
cout<<endl<<" >>>>>>>>>总里程为"<<D[v][w]<<"米,考虑换乘以及等车一共约用时为:"<<e+T<<"分钟,票价为"<<value<<"元!!!!"<<endl<<endl<<endl<<endl<<endl<<endl;
cout<<" >>>>>>>>>是否继续查询?(Y/N)";
scanf("%s",&s);
if(s!='y'&&s!='Y')
break;
else
system("cls");
}
}
int main()
{
MTGraph G1,G2,G3;
char a,d;
int c;
char b[10];
scanf("%s",&d);
system("cls");
if(d=='2')
{
CreateGraph_2(G2);
Pathmatrix P;
ShortPathTable D;
ShortestPath(G2,P,D);
printf("\n");
printf("请按Enter键返回上一级菜单");
_getch();
system("cls");
}
return 0;
}
初始定义了一个结构体中的数组,大小为405,在dev上能够正常运行,但在VS2019上则出现异常。