地铁换乘最短路径

来源:互联网 发布:js怎么修改属性 编辑:程序博客网 时间:2024/04/29 00:15

本文转自:http://www.linuxidc.com/Linux/2013-10/90915.htm


华为2014上机考试样题_高级题_地铁换乘最短路径_无向无权图+邻接表存储+BFS广度优先算法

/*
Copyright (c) 2013, binzhouweichao@163.com

华为2014上机考试样题 高级题 地铁换乘 最短路径 http://www.linuxidc.com/Linux/2013-10/90916.htm

华为2014校园招聘经历_底层软件研发_机考 http://www.linuxidc.com/Linux/2013-10/90912.htm

华为2014机考题目_判断if括号匹配是否合法_堆栈_简单的方法- - http://www.linuxidc.com/Linux/2013-10/90913.htm

华为2014机考题_判断if括号是否匹配_堆栈 http://www.linuxidc.com/Linux/2013-10/90914.htm

无向无权图 邻接表存储 BFS广度优先算法搜索
涉及:图 链表 队列 指针 数组 字符串 类型转换

供参考

*/

/*


*/


#include <iostream> #include <string>  //用到字符串操作#include <sstream>  //int转string,用到流操作using namespace std;  //标准库命名空间#define DEBUG#define VerNum 35 //定义顶点数,为 35=18(A)+15(B)+2(T)typedef int Boolean;#define TRUE 1#define FALSE 0/*********************字符串数组与编号映射*************************************Adata: A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16 A17 A18index: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17Bdata: B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15index: 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32Tdata: T1 T2index: 33 34*/string Data[VerNum]; //字符串数组,用于存储输入的字符串,数据和下标构成上述映射关系;全局变量string intToString(int index)  //int转string函数,用于下述 initD() 的字符串序号{stringstream str1;string str2;str1 << index;str1 >> str2;return str2;}void InitData()   //初始化字符串数组,完成映射{int index;for (index = 0; index < 18; index++)  //A1-A18, index 0-17Data[index] = "A" + intToString(index + 1);for (index = 18; index < 33; index++)  //B1-B15, index 18-32Data[index] = "B" + intToString(index - 18 + 1);for (index = 33; index < 35; index++)  //T1-T2, index 33-34Data[index] = "T" + intToString(index - 33 + 1);}int dataToIndex(string str)   //查找输入字符串的相应index{int index;for (index = 0; index < VerNum; index++){if(strcmp(str.c_str(),Data[index].c_str()) == 0) //比较输入字符串str与数据数组Data[]的各元素,相等则返回该元素下标indexbreak;}return index;}/**************************************************************邻接表存储图信息******************************Data index  顶点表GraphList    第一边表e1[35]   第二边表e2[33]   第三边表e3[2]   第四边表e4[2]     verIndex firstedge eVerIndex nextEdge eVerIndex nextEdge eVerIndex nextEdge eVerIndex nextEdge-----------------------------------------------------------------------------------------------------------------------------------------------A1  0  |  0  -->  |e1[0] 1  -->  |e2[0] 17  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------A2  1  |  1  -->  |  2  -->  |  0  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------A3  2  |  2  -->  |  3  -->  |  1  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------A4  3  |  3  -->  |  4  -->  |  2  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------A5  4  |  4  -->  |  5  -->  |  3  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------A6  5  |  5  -->  |  6  -->  |  4  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------A7  6  |  6  -->  |  7  -->  |  5  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------A8  7  |  7  -->  |  8  -->  |  6  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------A9  8  |  8  -->  |  33(T1) -->  |  7  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------A10  9  |  9  -->  |  10  -->  |  33(T1) -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------A11  10  |  10  -->  |  11  -->  |  9  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------A12  11  |  11  -->  |  12  -->  |  10  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------A13  12  |  12  -->  |  34(T2) -->  |  11  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------A14  13  |  13  -->  |  14  -->  |  34(T2) -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------A15  14  |  14  -->  |  15  -->  |  13  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------A16  15  |  15  -->  |  16  -->  |  14  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------A17  16  |  16  -->  |  17  -->  |  15  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------A18  17  |  17  -->  |  0  -->  |e2[17] 16  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------B1  18  |  18  -->  |  19  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------B2  19  |  19  -->  |  20  -->  |e2[18] 18  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------B3  20  |  20  -->  |  21  -->  |  19  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------B4  21  |  21  -->  |  22  -->  |  20  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------B5  22  |  22  -->  |  33(T1) -->  |  21  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------B6  23  |  23  -->  |  24  -->  |  33(T1) -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------B7  24  |  24  -->  |  25  -->  |  23  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------B8  25  |  25  -->  |  26  -->  |  24  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------B9  26  |  26  -->  |  27  -->  |  25  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------B10  27  |  27  -->  |  34(T2) -->  |  26  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------B11  28  |  28  -->  |  29  -->  |  34(T2) -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------B12  29  |  29  -->  |  30  -->  |  28  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------B13  30  |  30  -->  |  31  -->  |  29  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------B14  31  |  31  -->  |  32  -->  |e2[30] 30  -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------B15  32  |  32  -->  |  31(B14) -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------T1  33  |  33  -->  |e1[33] 9(A10) -->  |e2[31] 8(A9) -->  |e3[0] 23(B6) -->  |e4[0] 22(B5) -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------T2  34  |  34  -->  |e1[34] 13(A14) -->  |e2[32] 12(A14) -->  |e3[1] 28(B11) -->  |e4[1] 27(B10) -->NULL |-----------------------------------------------------------------------------------------------------------------------------------------------参考:http://blog.chinaunix.net/uid-26548237-id-3483650.html*///边表结构typedef struct edgeNode{int eVerIndex; //边表顶点号struct edgeNode *nextEdge; //指向下一边表的指针}edgeNode; //struct edgeNode的别名为edgeNode,方便调用//顶点表结构typedef struct vertexNode{int verIndex; //顶点表的顶点号edgeNode *firstEdge; //指向第一边表的指针}vertexNode;//顶点表构成的图的邻接表typedef struct{vertexNode adjList[VerNum]; //顶点表结构数组,总数为顶点的数目}graphList; //将此结构体别名定义为graphList//建图,确立顶点表和边表的关系,完善各表的数据域和指针域void CreatGraph(graphList *g)//指针形参,对g指向的内容的操作在函数结束后仍然有效{/**************边表************************///边表和顶点表的填充过程参考上面的邻接表图edgeNode *e1[35];//第一边表edgeNode *e2[33];//第二边表edgeNode *e3[2];//第三边表edgeNode *e4[2];//第四边表int i;for (i = 0; i < 35; i++)//第一边表初始化,分配内存e1[i] = new edgeNode;for (i = 0; i < 33; i++)//第二边表初始化,分配内存e2[i] = new edgeNode;for (i = 0; i < 2; i++)    //第三、四边表初始化,分配内存{e3[i] = new edgeNode;e4[i] = new edgeNode;}//第一边表数据域,即第一边表顶点号//Afor (i = 0; i < 18; i++)e1[i]->eVerIndex = i + 1;//修正Ae1[8]->eVerIndex = 33;//A9-->T1e1[12]->eVerIndex = 34;//A13-->T2e1[17]->eVerIndex = 0;//A18-->A1//Bfor (i = 18; i < 18+15; i++)e1[i]->eVerIndex = i + 1;//修正Be1[22]->eVerIndex = 33;//B5-->T1e1[27]->eVerIndex = 34;//B10-->T2e1[32]->eVerIndex = 31;//B15-->B14//T1 T2e1[33]->eVerIndex = 9;//T1-->A10e1[34]->eVerIndex = 13;//T2-->A14//第二边表数据域,即第二边表顶点号//Afor (i = 0; i < 18; i++)e2[i]->eVerIndex = i - 1;//修正Ae2[0]->eVerIndex = 17;//A1-->A18e2[9]->eVerIndex = 33;//A10-->T1e2[13]->eVerIndex = 34;//A14-->T2//Bfor(i=18; i<31; i++)//B1和B15没有第二边表e2[i]->eVerIndex = i;//修正Be2[22]->eVerIndex = 33; //B6-->T1e2[27]->eVerIndex = 34; //B11-->T2//T1 T2e2[31]->eVerIndex = 8;//T1-->A9e2[32]->eVerIndex = 12;//T2-->A13//第三边表数据域,即第三边表顶点号//T1 T2e3[0]->eVerIndex = 23;//T1-->B6e3[1]->eVerIndex = 28;//T2-->B11//第四边表数据域,即第四边表顶点号//T1 T2e4[0]->eVerIndex = 22;//T1-->B5e4[1]->eVerIndex = 27;//T2-->B10//第一边表指针域for (i = 0; i < 18; i++)e1[i]->nextEdge = e2[i];e1[18]->nextEdge = NULL;//B1没有第二边表for (i = 19; i < 32; i++)e1[i]->nextEdge = e2[i-1];e1[32]->nextEdge = NULL;//B15没有第二边表e1[33]->nextEdge = e2[31];e1[34]->nextEdge = e2[32];//第二边表指针域for (i = 0; i < 31; i++)e2[i]->nextEdge = NULL;e2[31]->nextEdge = e3[0];e2[32]->nextEdge = e3[1];//第三边表指针域e3[0]->nextEdge = e4[0];e3[1]->nextEdge = e4[1];//第四边表指针域e4[0]->nextEdge = NULL;e4[1]->nextEdge = NULL;/*************************************************************//***完善顶点表数据域和指针域,关联顶点表与第一边表****/for (i = 0; i < VerNum; i++){g->adjList[i].verIndex = i;//顶点表数据域g->adjList[i].firstEdge = e1[i];//顶点表指针域}/*************************************************************/}/***打印邻接表信息*******/#ifdef DEBUG //只在DEBUG模式下打印void printGraph(graphList *g){int i;edgeNode *p;for (i = 0; i < VerNum; i++){cout << "顶点号:" << i << "边号:";p = g->adjList[i].firstEdge;while (p){cout << p->eVerIndex << " ";p = p->nextEdge;}cout << endl;}}#endif/***************************************************//****BFS广度优先搜索邻接表,找出最短路径***********参考:http://blog.163.com/zhoumhan_0351/blog/static/3995422720098711040303/******************************************************///队列链表结点结构,单向链表typedef struct qNote{int qVerIndex;//队列数据域,结点存储的顶点号struct qNote *nextQNode;//队列指针域,结点指向的下一个队列结点}qNote;//队列链表typedef struct{qNote *front;//队列头,删除qNote *rear;//队列尾,添加}queue;//初始化队列,新建队列void InitQueue(queue *q){q->rear = new qNote;//新建队列结点,赋予队尾q->front = q->rear;//空队列的队头与队尾为同一单元/*if(q->front == NULL) //分配单元失败{cout << "InitQueue Error!" << endl;exit(1);}*/q->front->nextQNode = NULL;//队头的指向下一结点的指针为空//因为队首队尾为同一单元,则队尾结点的下一结点指针也为空,即q->rear->nextQNode == NULL}//入队,队尾添加void EnQueue(queue *q, int e)//形参为队列q地址,要添加的新的队列结点的数据域{qNote *p = new qNote;//新建节点,并分配内存/*if(p == NULL ) //若分配内存失败则退出{cout << "EnQueue Error!" << endl;exit(1);}*/p->qVerIndex = e;p->nextQNode = NULL;q->rear->nextQNode = p;//原队尾指向下一结点的指针指向pq->rear = p;//p成为新的队尾}int QueueEmpty(queue *q)//判断队列是否为空,空则返回1,非空为0{return (q->front == q->rear ? 1:0);//判断条件为,队头与队尾为同一单元}//出队,队首删除void DeQueue(queue *q, int *m) //队列q指针传参,m为指针形参,用于保存删除的结点的数据域{qNote *p = new qNote;//新建队列结点,用于缓存if (QueueEmpty(q))//若为空队列,则报错退出{cout<<"DeQueue Error!"<<endl;exit(1);}p = q->front->nextQNode;//要删除的结点缓存为p*m = p->qVerIndex;//要删除的结点的数据域放入m所指单元q->front->nextQNode = p->nextQNode;//队头指向下一结点的指针,即指向要删除的结点的下一个结点if (q->front->nextQNode == NULL){q->rear = q->front;//若队首指向下一个结点的指针为空,则表明队列已经清空,队首队尾为同一单元//注:不能写反了}free(p);//释放缓存}//BFS广度优先搜索void BFSTraverse(graphList *g, int dist[VerNum][VerNum]){queue q;edgeNode *p = new edgeNode;//定义边表结点类型指针,下面访问各个结点的边表时用到int index;/*此处使用循环来得到所有点相对其他点的最短路径,若图有未达到的点,需要再设置一个循环来达到遍历所有点的目的,因为此题中任何点均可以达到其他所有点,不必再设下一循环*/for (index = 0; index < VerNum; index++){InitQueue(&q);//初始化队列q,每个新的起点都重置一下队列Boolean visited[VerNum] = {FALSE};//定义各顶点访问标志,并初始化为FALSE/*设置一个层次标志BFS算法是把图从一个顶点转化为树,并按照距离的远近设置树的层次,处于同一层次的叶结点与根结点的距离相同而且根结点与页结点的距离,就是层次数*/int level[VerNum][VerNum];//树的最大度为VerNum(第一个),每层中最大叶结点为VerNum(第二个)//此数组用于保存每层的各叶子结点int r1,r2;//数组横下标为r1,纵下标r2for(r1=0; r1<VerNum; r1++) //初始化层次数组{for(r2=0; r2<VerNum; r2++)level[r1][r2] = VerNum; //因为没有VerNum序号的结点,用于判断是否赋值,或作其他用途}EnQueue(&q,index);//顶点入队visited[index] = TRUE;//入队表示已访问r1 = 0;r2 = 0;level[0][0] = index;//树的根节点存放的顶点号//r1表示层次数,r2表示本层的第几个叶结点dist[index][index] = r1;//表示该顶点到自身的距离为0while (!QueueEmpty(&q)){int m;DeQueue(&q,&m);//队首出队if (m == level[r1][0])//若出队的顶点号与第r1层的第一个结点的顶点号相同//即:出队的顶点号是某层第一个入队的结点,那么说明该层已经访问结束,进入下一层访问{r1 += 1;//进入下一层r2 = 0;//下一层起点}p = g->adjList[m].firstEdge;//按照邻接表各顶点边表的顺序访问每个顶点while (p){if (!visited[p->eVerIndex]){EnQueue(&q,p->eVerIndex);//未访问的入队visited[p->eVerIndex] = TRUE;//入队表示已访问level[r1][r2] = p->eVerIndex;//r1层r2叶结点的顶点号为当前访问的边表顶点号dist[index][p->eVerIndex] = r1;//根顶点与当前访问的顶点的距离,为当前访问的点所在的层次数r2 += 1;//该层访问结点数递增}p = p->nextEdge;//循环控制,指向下一个边表}}}}#ifdef DEBUGvoid printBFS(int dist[VerNum][VerNum]){cout<<endl;for (int i = 0; i < VerNum; i++){cout<<i<<":";for (int j = 0; j < VerNum; j++){cout<<dist[i][j]<<" ";}cout<<endl;}}#endifint main(){InitData();//初始化字符串数组,Data[]数组已经设置成了全局变量。。也可以设置在此处数组传参graphList g;//建图CreatGraph(&g);//完善图的所有结点#ifdef DEBUG //调试用,打印图printGraph(&g);#endifint dist[VerNum][VerNum]; //定义各顶点间距离数组for(int d1=0; d1<VerNum; d1++) //初始化距离数组{for(int d2=0; d2<VerNum; d2++){dist[d1][d2] = 0; //表示顶点d1到顶点d2的距离//最大距离不会是VerNum,表示无法到达或有其他用途}}BFSTraverse(&g, dist); //BFS搜索,保存各点最短路径#ifdef DEBUGprintBFS(dist); //打印各点间最短路径#endifstring str1, str2; //用于保存两个输入的字符串#ifdef DEBUGcout << "请输入两个站点:" << endl;#endifcin >> str1 >> str2; //输入两个字符串,没有设置冗余,对于不符合规范的输入,只取前两个int index1, index2; //用于保存将两个输入的字符串转换后的顶点号index1 = dataToIndex(str1); //将str1转换成相应顶点号index2 = dataToIndex(str2); //将str2转换成相应顶点号//两点index1和index2间的距离即为dist[index1][index2],无向,则也等于dist[index2][index1]#ifdef DEBUGcout << "两点间站点数为:" << endl;#endifcout << dist[index1][index2] <<endl;#ifdef DEBUGsystem("pause"); //暂停,以查看输出#endifreturn 0;}

用Floyd算法,简单易理解,但时间复杂度是n^3。

参考:http://blog.csdn.net/suren__123/article/details/10985305   原文个别错误已改。

  1. #include <cstdlib>    
  2. #include <iostream>    
  3. #include <string>  
  4.   
  5. /*  
  6. Author : 俗人 
  7. Time : 2013/9/2  
  8. description : 地铁换乘问题  
  9.  
  10. 已知2条地铁线路,其中A为环线,B为东西向线路,线路均为双向, 
  11. 换乘点为 T1,T2,编写程序,任意输入两个站点名称,输出乘坐地铁 
  12. 最少所需要经过的车站数量 
  13.  
  14. A(环线):A1...A9 T1 A10...A13 T2 A14...A18  
  15. B(直线):B1...B5 T1 B6...B10 T2 B11...B15  
  16.  
  17. 样例输入:A1 A3 
  18. 样例输出:3  
  19.  
  20. */     
  21.   
  22. using namespace std;  
  23.   
  24. //无向图的数据结构    
  25. struct Graph    
  26. {    
  27.        int arrArc[100][100];  //邻接矩阵   
  28.        int verCount;  //点数   
  29.        int arcCount;  //边数   
  30.        };    
  31.   
  32. //FLOYD算法 求任意两点最短路径矩阵         
  33. void floyd(Graph *p,int dis[100][100]){    
  34.          
  35.      for(int k = 1;k <= p->verCount;k++)    
  36.         for(int i = 1; i <= p->verCount;i++)    
  37.            for(int j = 1;j <= p->verCount;j++)    
  38.            {    
  39.                    //存在更近的路径,则更新      
  40.                    if(dis[i][j]>dis[i][k]+dis[k][j])    
  41.                    dis[i][j]=dis[i][k]+dis[k][j];    
  42.            }    
  43.          
  44.      }    
  45.        
  46.        
  47. //站名字符串转节点编号       
  48. int  char_to_int(string s){    
  49.          
  50.      string s1[38] = {"A0","A1","A2","A3","A4","A5","A6","A7","A8","A9","A10",  
  51.                     "A11","A12","A13","A14","A15","A16","A17","A18",  
  52.                     "B1","B2","B3","B4","B5","B6","B7","B8","B9","B10",  
  53.                     "B11","B12","B13","B14","B15","T1","T2"} ;  
  54.       
  55.      for(int i=1 ; i <= 38;i ++){              
  56.             if (s == s1[i])  
  57.             return i;              
  58.      }  
  59.        
  60.      return -1;         
  61.      }    
  62.     
  63.     
  64. int main(int argc, char *argv[])    
  65. {    
  66.     Graph g;    
  67.       
  68.     g.verCount = 35;    //原文有误
  69.     g.arcCount = 36;    //原文有误
  70.       
  71.     cout<<"number of ver:"<<g.verCount<<" number of arc:" <<g.arcCount<<endl;    
  72.       
  73.     //初始化邻接矩阵      
  74.     for(int i = 1;i<=g.verCount;i++)    
  75.     { for(int j = 1;j<=g.verCount;j++)    
  76.        {    
  77.               //i到本身的距离为0     
  78.               //不同节点值为不可达      
  79.               if(i==j) g.arrArc[i][i]= 0;    
  80.               else    
  81.               g.arrArc[i][j] = 65535;    
  82.        }    
  83.     }     
  84.               
  85.     //输入A环线个点相连情况 每个边权重都为1           
  86.     int a[21] = {1,2,3,4,5,6,7,8,9,34,10,11,12,13,35,14,15,16,17,18,1};      
  87.     for(int i=0;i<20;i++)    
  88.     {    
  89.         g.arrArc[a[i]][a[i+1]] = 1;   
  90.         g.arrArc[a[i+1]][a[i]] = 1;        
  91.     }    
  92.       
  93.     //输入B线个点相连情况 每个边权重都为1   
  94.     int b[17] = {19,20,21,22,23,34,24,25,26,27,28,35,29,30,31,32,33};     
  95.     for(int i=0;i<16;i++)    
  96.     {     
  97.         g.arrArc[b[i]][b[i+1]] = 1;   
  98.         g.arrArc[b[i+1]][b[i]] = 1;          
  99.     }   
  100.       
  101.     //计算邻接矩阵   
  102.     floyd(&g,g.arrArc);        
  103.       
  104.     cout << "请输入起始站点:" <<endl;   
  105.     string start;   
  106.     string end;         
  107.     cin >> start >> end;  
  108.     cout << g.arrArc[char_to_int(start)][char_to_int(end)] <<endl;  
  109.       
  110.     system("PAUSE");      
  111.     return EXIT_SUCCESS;    
  112. }    

0 0
原创粉丝点击