4、【4】公交线路提示 (必做)(图)
[问题描述]
上网下载真实南京公交线路图,建立南京主要公交线路图的存储结构。
[基本要求]
(1)输入任意两站点,给出转车次数最少的乘车路线。
(2)输入任意两站点,给出经过站点最少的乘车路线。
#include <iostream>
#include <fstream>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <sstream>
#include <time.h>
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <windows.h>
#define OK 1
#define TRUE 1
#define FALSE 0
#define MAXSIZE 65536
#define INFINIT 0x3f3f3f3f
#define SIZE 256
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define NUM 99999
using namespace std;
typedef int Status;
typedef int ElemType;
typedef int T;
//Queue 部分
struct QNode{
// T data;
ElemType data;
QNode* next;
};
struct Queue{
QNode *front; //队头指针(链表头)
QNode *rear; //队尾指针(链表尾)
};
struct ArcNode{
ElemType adjvex;
ElemType road; //No.
ArcNode* nextarc; //next
};
struct VNode{
char name[50];
ArcNode* firstarc;
};
struct ALGraph{
VNode vertices[6000]; //顶点
ElemType vexnum, arcnum; //连接站点数量,弧
ElemType* visited;
};
typedef struct Arc{
int adjvex;
Arc* nextarc;
}arc;
struct BusNode{
arc* firstarc;
};
struct LGraph{
BusNode vertices[1000]; //顶点
ElemType vexnum, arcnum; //顶点数,弧数
ElemType* visited;
};
struct Stack{
ElemType* data;
ElemType* base;
ElemType* top;
ElemType stacksize;
};
float min(float a, float b){
return a<b?a:b;
}
void CreateQueue(Queue Q){ //Queue
Q.front = Q.rear = new QNode;
Q.front->next = NULL;
}
void DeleteQueue(Queue Q){ //~Queue
QNode * p, * q;
p = q = Q.front;
while (p != NULL)
{
p = p->next;
delete q;
q = p;
}
Q.front = Q.rear = NULL;
}
void ClearQueue(Queue Q){
QNode* p, * q;
p = q = Q.front->next;
while (p != NULL)
{
p = p->next;
delete q;
q = p;
}
Q.rear = Q.front;
}
Status QueueEmpty(Queue Q){
if (Q.front == Q.rear){
return TRUE;
}
else{
return FALSE;
}
}
Status QueueLength(Queue Q){
int count = 0;
QNode * p;
p = Q.front->next;
while (p != NULL)
{
count++;
p = p->next;
}
return count;
}
QNode* GetHead(Queue Q){ //取得头QNode
if (Q.front == Q.rear){
cout << "Queue Empty" << endl;
return NULL;
}
else{
return Q.front->next;
}
}
void EnQueue(Queue Q,ElemType E){
QNode * p;
p = new QNode;
p->data = E;
p->next = NULL;
Q.rear->next = p;
Q.rear = Q.rear->next;
}
Status DeQueue(Queue Q){ //Delete Queue
if (Q.front == Q.rear){
cout << "Queue Empty" << endl;
}
else{
ElemType ans;
QNode* p;
p = Q.front->next;
ans = p->data;
Q.front->next = p->next;
if (Q.rear == p) {
Q.rear = Q.front;
}
delete p;
return ans;
}
}
//Queue
void CreateStack(Stack S) {
S.data = new ElemType[SIZE];
S.top = S.base = S.data;
S.stacksize = SIZE;
}
void ClearStack(Stack S){
S.top = S.base;
}
Status StackEmpty(Stack S){
if (S.top == S.base){
return TRUE;
}
else{
return FALSE;
}
}
Status StackLength(Stack S){
return S.top - S.base;
}
ElemType GetTop(Stack S){
return *(S.top - 1);
}
ElemType* GetBaseLoca(Stack S){
return S.base;
}
void Push(Stack S,ElemType num){ //进栈
if (S.top - S.base != S.stacksize){
*(S.top) = num;
S.top++;
}
else{
int i;
ElemType* tmp;
tmp = new ElemType[S.stacksize + STACKINCREMENT];
for (i = 0; i < S.stacksize; i++)
{
tmp[i] = S.data[i];
}
delete[]S.data;
S.data = tmp;
S.stacksize += STACKINCREMENT;
*(S.top) = num;
S.top++;
}
}
ElemType Pop(Stack S){
if (S.top != S.base){
S.top--;
return *(S.top);
}
else
{
return 0;
}
}
void ShowStack(Stack S){
int i;
if (S.top - S.base == 0){
cout << "Stack Empty" << endl;
}
else{
cout << "栈底到栈顶:";
for (i = 0; i < S.top - S.base; i++){
cout << S.data[i] << " ";
}
cout << endl;
}
}
void AddArcNode(ALGraph A ,int v1, int v2, int road){
ArcNode* Ap;
Ap = A.vertices[v1].firstarc;
if (Ap == NULL){
A.vertices[v1].firstarc = new ArcNode;
A.vertices[v1].firstarc->adjvex = v2;
A.vertices[v1].firstarc->road = road;
A.vertices[v1].firstarc->nextarc = NULL;
}
else {
while (Ap->nextarc != NULL){
Ap = Ap->nextarc;
}
Ap->nextarc = new ArcNode;
Ap = Ap->nextarc;
Ap->adjvex = v2;
Ap->road = road;
Ap->nextarc = NULL;
}
Ap = A.vertices[v2].firstarc;
if (Ap == NULL){
A.vertices[v2].firstarc = new ArcNode;
A.vertices[v2].firstarc->adjvex = v1;
A.vertices[v2].firstarc->road = road;
A.vertices[v2].firstarc->nextarc = NULL;
}
else{
while (Ap->nextarc != NULL){
Ap = Ap->nextarc;
}
Ap->nextarc = new ArcNode;
Ap = Ap->nextarc;
Ap->adjvex = v1;
Ap->road = road;
Ap->nextarc = NULL;
}
A.arcnum++; //边数++
}
void CreateALGraph(ALGraph &A){
A.arcnum = 0;
int i, j, count;
int road;
int pre_p;
fstream file;
ArcNode* Ap;
char str[MAXSIZE];
file.open("text4.txt", ios::in);
if (file.fail())
{
cout << "Target File Open Fail" << endl;
exit(0);
}
A.vexnum = 0;
road = 0; //int
count = 0;
while (!file.eof()){
file >> road;
if (file.eof()){
break;
}
file.getline(str, MAXSIZE, '\n');
i = 0;
while (str[i] != ' ')
i++;
while (str[i] == ' ')
i++;
while (1){
for (j = 0; str[i] != ',' && str[i] != '\0'; i++, j++){
A.vertices[A.vexnum].name[j] = str[i];
}
A.vertices[A.vexnum].name[j] = '\0';
for (j = 0; j < A.vexnum; j++){
if (strcmp(A.vertices[j].name, A.vertices[A.vexnum].name) == 0){
if (count > 0){
AddArcNode(A , j, pre_p, road);
}
pre_p = j;
count++;
break;
}
}
if (j == A.vexnum){
A.vertices[A.vexnum].firstarc = NULL;
if (count > 0){
AddArcNode(A, pre_p, A.vexnum, road);
}
pre_p = A.vexnum;
A.vexnum++;
count++;
}
if (str[i] != '\0'){
i++;
}
else{
break;
}
}
pre_p = 0;
count = 0;
}
file.close();
A.visited = new int[A.vexnum];
/*
A->arcnum = 0;
int i, j, count;
int road;
int pre_p;
fstream rf;
ArcNode* Ap;
char str[3000];
rf.open("text4-2.txt", ios::in);
if (rf.fail())
{
cout << "目标文件打开失败" << endl;
exit(0);
}
A->vexnum = 0;
road = 0;
count = 0;
while (!rf.eof())
{
rf >> road;
if (rf.eof())
{
break;
}
rf.getline(str, 3000, '\n');
i = 0;
while (str[i] != ' ') i++;
while (str[i] == ' ') i++;
while (1)
{
for (j = 0; str[i] != ',' && str[i] != '\0'; i++, j++)
{
A->vertices[A->vexnum].name[j] = str[i];
}
A->vertices[A->vexnum].name[j] = '\0';
for (j = 0; j < A->vexnum; j++)
{
if (strcmp(A->vertices[j].name, A->vertices[A->vexnum].name) == 0)
{
if (count > 0)
{
AddArcNode(*A ,j, pre_p, road);
}
pre_p = j;
count++;
break;
}
}
if (j == A->vexnum)
{
A->vertices[A->vexnum].firstarc = NULL;
if (count > 0)
{
AddArcNode(*A,pre_p, A->vexnum, road);
}
pre_p = A->vexnum;
A->vexnum++;
count++;
}
if (str[i] != '\0')
{
i++;
}
else
{
break;
}
}
pre_p = 0;
count = 0;
}
rf.close();
A->visited = new int[A->vexnum];
*/
}
void DeleteALGraph(ALGraph A){
ArcNode* Ap, * pre_Ap;
for (int i = 0; i < A.vexnum; i++)
{
Ap = A.vertices[i].firstarc;
if (Ap == NULL);
else
{
pre_Ap = Ap;
while (1)
{
Ap = Ap->nextarc;
if (Ap == NULL)
{
break;
}
delete pre_Ap;
pre_Ap = Ap;
}
}
}
}
ArcNode* AdjVex(ALGraph A,int i){
ArcNode* Ap;
Ap = A.vertices[i].firstarc;
if (Ap == NULL){
return NULL;
}
else{
return Ap;
}
}
ElemType GetVexNum(ALGraph A){
return A.vexnum;
}
ElemType FindRoad(ALGraph A,char* n){
for (int i = 0; i < A.vexnum; i++){
if (strcmp(A.vertices[i].name, n) == 0){
return i;
}
}
return -1;
}
ElemType IsAdjALG(ALGraph A,int i, int j){
ArcNode* Ap;
Ap = A.vertices[i].firstarc;
if (Ap == NULL);
else
{
while (Ap != NULL)
{
if (Ap->adjvex == j)
{
return TRUE;
}
Ap = Ap->nextarc;
}
}
Ap = A.vertices[j].firstarc;
if (Ap == NULL);
else
{
while (Ap != NULL)
{
if (Ap->adjvex == i)
{
return TRUE;
}
Ap = Ap->nextarc;
}
}
return FALSE;
}
void MiniRoad(ALGraph A,char* start, char* end){ //广度
for (int i = 0; i < A.vexnum; i++){
A.visited[i] = 0;
}
int v, u;
int s, e;
ArcNode* w = NULL;
int i, j;
int flag = 0;
Queue Q;
for (i = 0; i < A.vexnum; i++){
if (strcmp(start, A.vertices[i].name) == 0)
{
s = i;
}
if (strcmp(end, A.vertices[i].name) == 0)
{
e = i;
}
}
v = s;
A.visited[v] = 1;
EnQueue(Q,v);
while (!QueueEmpty(Q)){
if (flag == 1){
break;
}
u = DeQueue(Q);
for (w = A.vertices[u].firstarc; w != NULL; w = w->nextarc){
if (A.visited[w->adjvex] == 0)
{
A.visited[w->adjvex] = A.visited[u] + 1;
if (w->adjvex == e){
flag = 1;
break;
}
EnQueue(Q,w->adjvex);
}
}
}
ArcNode* Ap;
Stack S_sta;
Stack S_road;
Push(S_sta,w->adjvex);
i = w->adjvex;
cout << "Least After Station:" << endl;
cout << "Total:" << A.visited[w->adjvex] << "Site" << endl;
for (int deep = A.visited[w->adjvex] - 1; deep > 1; deep--){
for (j = 0; j < A.vexnum; j++){
if (A.visited[j] == deep && IsAdjALG(A,i, j)){
Push(S_sta,j);
i = j;
break;
}
}
}
cout << A.vertices[s].name;
i = s;
while (!StackEmpty(S_sta)){
cout << "->";
j = Pop(S_sta);
Ap = A.vertices[j].firstarc;
while (Ap->adjvex != i){
Ap = Ap->nextarc;
}
if (StackEmpty(S_road) || (GetTop(S_road) != Ap->road)){
Push(S_road,Ap->road);
}
cout << A.vertices[j].name;
i = j;
}
cout << endl << endl;
cout << "Your Route is:" << endl;
cout << "Total:" << StackLength(S_road) << "Buses" << endl;
cout << Pop(S_road) << "Site";
while (!StackEmpty(S_road))
{
cout << "——>";
cout << Pop(S_road) << "Site";
}
cout << endl << endl;
}
void AddArc(LGraph L,int v1, int v2){
int flag;
arc* Ap;
Ap = L.vertices[v1].firstarc;
if (Ap == NULL){
L.vertices[v1].firstarc = new arc;
L.vertices[v1].firstarc->adjvex = v2;
L.vertices[v1].firstarc->nextarc = NULL;
}
else{
flag = 0;
while (Ap->nextarc != NULL){
if (Ap->adjvex == v2)
flag = 1;
Ap = Ap->nextarc;
if (Ap->adjvex == v1)
flag = 1;
}
if (!flag){
Ap->nextarc = new arc;
Ap = Ap->nextarc;
Ap->adjvex = v2;
Ap->nextarc = NULL;
}
}
Ap = L.vertices[v2].firstarc;
if (Ap == NULL){
L.vertices[v2].firstarc = new arc;
L.vertices[v2].firstarc->adjvex = v1;
L.vertices[v2].firstarc->nextarc = NULL;
}
else
{
flag = 0;
while (Ap->nextarc != NULL)
{
if (Ap->adjvex == v1) flag = 1;//说明两辆车可以换乘的信息已经记录了
Ap = Ap->nextarc;
if (Ap->adjvex == v1) flag = 1;//说明两辆车可以换乘的信息已经记录了
}
if (!flag)
{
Ap->nextarc = new arc;
Ap = Ap->nextarc;
Ap->adjvex = v1;
Ap->nextarc = NULL;
}
}
L.arcnum++;
}
void CreateLGraph(LGraph &L,ALGraph &G){
L.vexnum = 0;
ArcNode* Ap;
arc* Bp;
int i, j, k;
int count;
int Bus[500];
for (i = 0; i < G.vexnum; i++){
Ap = G.vertices[i].firstarc;
for (j = 0; j < 500; j++){
Bus[j] = 0;
}
if (Ap == NULL){
continue;
}
else{
count = 0;
while (Ap != NULL){
for (k = 0; k < count; k++){
if (Ap->road == Bus[k]){
break;
}
}
if (k == count){
Bus[count++] = Ap->road;
if (Ap->road > L.vexnum){
L.vexnum = Ap->road;
}
}
Ap = Ap->nextarc;
}
for (k = 0; k < count - 1; k++){
for (j = k + 1; j < count; j++){
if (Bus[j] != Bus[k]){
AddArc(L,Bus[j], Bus[k]);
}
}
}
}
}
L.visited = new int[L.vexnum + 1];
}
Status DeleteGraph(LGraph L){
arc* Ap, * pre_Ap;
for (int i = 1; i < L.vexnum + 1; i++)
{
Ap = L.vertices[i].firstarc;
if (Ap == NULL);
else
{
pre_Ap = Ap;
while (1)
{
Ap = Ap->nextarc;
if (Ap == NULL)
{
break;
}
delete pre_Ap;
pre_Ap = Ap;
}
}
}
return OK;
}
Status IsAdjLG(LGraph L,int i, int j){
arc* Ap;
Ap = L.vertices[i].firstarc;
if (Ap == NULL);
else
{
while (Ap != NULL)
{
if (Ap->adjvex == j)
{
return TRUE;
}
Ap = Ap->nextarc;
}
}
Ap = L.vertices[j].firstarc;
if (Ap == NULL);
else
{
while (Ap != NULL)
{
if (Ap->adjvex == i)
{
return TRUE;
}
Ap = Ap->nextarc;
}
}
return FALSE;
}
Status FindMinTime(LGraph L,int start, int end){ //广度
if (start == end){
return 0;
}
for (int i = 1; i < L.vexnum + 1; i++){
L.visited[i] = 0;
}
int v, u;
arc* w = NULL;
int i, j;
int flag = 0;
Queue Q;
v = start;
L.visited[v] = 1;
EnQueue(Q,v);
while (!QueueEmpty(Q))
{
if (flag == 1){
break;
}
u = DeQueue(Q);
for (w = L.vertices[u].firstarc; w != NULL; w = w->nextarc)
{
if (L.visited[w->adjvex] == 0)
{
L.visited[w->adjvex] = L.visited[u] + 1;
if (w->adjvex == end){
flag = 1; //已经走到了终点
break;
}
EnQueue(Q,w->adjvex);
}
}
}
return L.visited[w->adjvex];
}
void PrintMinTransform(LGraph L,int start, int end){
if (start == end){
cout << "This 2 Station Stand On" << start << "Route Site" << endl;
return;
}
for (int i = 1; i < L.vexnum + 1; i++){
L.visited[i] = 0;
}
int v, u;
arc* w = NULL;
int i, j;
int flag = 0;
Queue Q;
v = start;
L.visited[v] = 1;
EnQueue(Q,v);
while (!QueueEmpty(Q)){
if (flag == 1){
break;
}
u = DeQueue(Q);
for (w = L.vertices[u].firstarc; w != NULL; w = w->nextarc){
if (L.visited[w->adjvex] == 0){
L.visited[w->adjvex] = L.visited[u] + 1;
if (w->adjvex == end){
flag = 1; //已经走到了终点
break;
}
EnQueue(Q,w->adjvex);
}
}
}
arc* Ap;
Stack S;
Push(S,w->adjvex);
i = w->adjvex;
cout << "Least After Station:" << endl;
if (L.visited[w->adjvex] <= 2){
cout << "No Need To Change Bus" << endl;
}
else{
cout << "Total Change Num:" << L.visited[w->adjvex] - 1 << "Time(s)" << endl;
}
for (int deep = L.visited[w->adjvex] - 1; deep > 1; deep--){
for (j = 0; j < L.vexnum; j++){
if (L.visited[j] == deep && IsAdjLG(L,i, j)){
Push(S,j);
i = j;
break;
}
}
}
cout << start;
i = start;
while (!StackEmpty(S)) {
cout << "->";
cout << Pop(S);
}
cout << endl << endl;
}
void MiniTransform(LGraph L,ALGraph* G, int start, int end){
int i, j;
for (i = 1; i < L.vexnum + 1; i++){
L.visited[i] = 0;
}
ArcNode* Ap;
int s_road[100];
int e_road[100];
int s_count = 0;
int e_count = 0;
char s[50];
char e[50];
Ap = G->vertices[start].firstarc;
while (Ap != NULL){
s_road[s_count++] = Ap->road;
Ap = Ap->nextarc;
}
Ap = G->vertices[end].firstarc;
while (Ap != NULL){
e_road[e_count++] = Ap->road;
Ap = Ap->nextarc;
}
int min =NUM;
int tmp = 0;
int min_s = 0;
int min_e = 0;
for (i = 0; i < s_count; i++){
for (j = 0; j < e_count; j++){
tmp = FindMinTime(L,s_road[i], e_road[j]);
if (tmp <= min){
min = tmp;
min_s = s_road[i];
min_e = e_road[j];
}
}
}
PrintMinTransform(L,min_s, min_e);
}
int main()
{
int start, end;
char s[50];
char e[50];
while(1)
{
system("cls");
cout<<"**********Welcome To Use Bus System**********"<<endl;
cout<<"Scanf 'break' To Break"<<endl;
cout << "Please Enter Your Start Point:"<<endl;
cin >> s;
if(strcmp(s,"break") == 0){
break;
}
cout << "Please Enter Your Final Point:"<<endl;
cin >> e;
if(strcmp(e,"break") == 0){
break;
}
ALGraph A;
CreateALGraph(A);
cout<<"Total "<<A.vexnum<<" "<<"Stations In File"<<endl;;
cout<<A.vertices[0].name<<endl; //read file error
cout<<A.vertices[1].name<<endl;
LGraph B;
CreateLGraph (B,A);
start = FindRoad(A,s);
// cout<<start<<endl;
end = FindRoad(A,e);
// cout<<end<<endl;
if (start == -1 || end == -1){
cout << "Your Enter Point Error" << endl;
// return 0;
system("pause");
continue;
}
if(start == end){
cout << "Your Start Just Your Final" <<endl;
// return 0;
system("pause");
continue;
}
MiniRoad(A, s, e);
cout << endl << endl << "Least Change:" << endl;
MiniTransform(B, &A, start, end);
system("pause");
}
system("pause");
return 0;
}