城市来往最短路线

书里面的一道题,记录一下代码。

原题大概是这么个样子:如下图所示表示的是从城市A到城市H的交通图。从图中可以看出,从城市A到城市H要经过若干个城市。现要找出一条经过城市最少的一条路线。

【算法分析】

看到这图很容易想到用邻接距阵来存储图中各节点的边的关系,1表示能走,0表示不能走。

首先想到的是用队列的思想。a数组是存储扩展结点的队列,a[i]记录经过的城市,b[i]记录前趋城市,这样就可以倒推出最短线路。具体过程如下:

(1) 将城市A入队,队首为0、队尾为1。

(2)将队首所指的城市所有可直通的城市入队(如果这个城市在队列中出现过就不入队,可用一布尔数组s[i]来判断),将入队城市的前趋城市保存在b[i]中。然后将队首加1,得到新的队首城市。重复以上步骤,直到搜到城市H时,搜索结束。利用b[i]可倒推出最少城市线路。

下面稍微细化一下题设:

输入n和e表示有n个城市,城市之间的连线有e条。然后输入e行,每行两个整数x和y表示城市x和y之间有边链接。

接着输入s和d表示出发点和目的点。

输出从s到d之间的最短路径(边的数量最少)以及路径长度 。

用于测试的输入数据:

8 12
A B
A F
A D
A C
B F
C D
C E
D G
E G
E H
F H
G H
A H

代码:

 1 #include <stdio.h>
 2
 3 #define maxN 1005
 4 #define maxE 5005
 5
 6 struct obj
 7 {
 8     int no,pre;
 9 };
10
11 int n,e;//无向图的n个顶点,e条边(顶点编号:1~n)
12 int p[maxN][maxN]={0};//邻接矩阵,无向图中各条边的数据
13 int begin,end;//出发点、终止点
14 struct obj a[maxN];//BFS队列
15 int head,tril;//队列的头、尾
16 int check[maxN]={0};//check[i]==0表示第i个顶点未曾入队
17 int flag=-1;//尚未搜索到终止点
18
19 void BFS();
20 void print();
21
22 int main(int argc, char *argv[])
23 {
24     //freopen("data.txt","r",stdin);
25     int i,x,y;
26     char xx,yy;
27     scanf("%d%d",&n,&e);getchar();
28     for(i=0;i<e;i++)
29     {
30         scanf("%c %c",&xx,&yy);getchar();
31         x=xx-‘A‘+1;  y=yy-‘A‘+1;
32         p[x-1][y-1]=1;
33         p[y-1][x-1]=1;
34     }
35     scanf("%c %c",&xx,&yy);
36     begin=xx-‘A‘+1;  end=yy-‘A‘+1;
37     begin--;
38     end--;
39     BFS();
40     if(flag==1) print();
41     else printf("no answer!\n");
42     return 0;
43 }
44 void BFS()
45 {
46     struct obj temp;
47     int j;
48     head=0;//初始化队列
49     tril=0;//初始化队列
50
51     a[tril].no=begin;//出发点入队
52     a[tril].pre=-1;//出发点不考虑前驱节点
53     check[begin]=1;//标记出发点已经入队
54
55     if(begin==end)
56     {
57         flag=1;
58         return ;//出发点和终止点相同,可以直接返回了。
59     }
60
61     while(tril-head+1>0)//当队列不为空时继续搜过
62     {
63         temp=a[head];
64          for(j=0;j<maxN;j++)//寻找temp节点的相邻节点,把相邻节点入队
65         {
66             if(p[temp.no][j]==1&&check[j]==0)//发现相邻节点j而且相邻节点j尚未入过队
67             {
68                 tril++;
69                 a[tril].no=j;//相邻节点j入队
70                 a[tril].pre=head;//相邻节点j的上一个节点(也就是temp节点)在队列当中的下标
71                 check[j]=1;
72                 if(j==end)
73                 {
74                     flag=1;//已经找到了终点end
75                     break;
76                 }
77             }
78         }
79         head++;//队头出队
80         if(flag==1)
81         {
82             break;
83         }
84     }
85 }
86 void print()
87 {
88     int i;
89     for(i=tril;i>=0;)
90     {
91         //printf("%d ",a[i].no+1);//输出节点编号(编号1~n)
92         printf("%c ",a[i].no+‘A‘);
93         i=a[i].pre;
94     }
95     printf("\n");
96 }

样例代码2:

  1 #include<stdio.h>
  2 #include<queue>
  3 #include<iostream>
  4 using namespace std;
  5
  6 #define maxN 1005
  7 #define maxE 5005
  8
  9 struct obj
 10 {
 11     int no,pre;
 12 };
 13
 14 int n,e;//无向图的n个顶点,e条边(顶点编号:1~n)
 15 int p[maxN][maxN]={0};//邻接矩阵,无向图中各条边的数据
 16 int begin,end;//出发点、终止点
 17 queue<obj> q;//BFS队列
 18 int s[maxN]={0};//用于记录出发点到目的点的路径。s[i]=k表节点i的前驱是节点k。
 19 int check[maxN]={0};//check[i]==0表示第i个顶点未曾入队
 20 int flag=-1;//尚未搜索到终止点
 21
 22 void BFS();
 23 void print();
 24
 25 int main()
 26 {
 27     freopen("data.txt","r",stdin);
 28     int i,x,y;
 29     char xx,yy;
 30     scanf("%d%d",&n,&e);getchar();
 31     for(i=0;i<e;i++)
 32     {
 33         scanf("%c %c",&xx,&yy);getchar();
 34         /*x=xx-‘A‘+1;  y=yy-‘A‘+1;
 35         p[x-1][y-1]=1;
 36         p[y-1][x-1]=1;*/
 37         x=xx-‘A‘; y=yy-‘A‘;
 38         p[x][y]=1;
 39         p[y][x]=1;
 40     }
 41     scanf("%c %c",&xx,&yy);
 42     /*begin=xx-‘A‘+1;  end=yy-‘A‘+1;
 43     begin--;
 44     end--;*/
 45     begin=xx-‘A‘;  end=yy-‘A‘;
 46
 47     BFS();
 48     if(flag==1) print();
 49     else printf("no answer!\n");
 50     return 0;
 51 }
 52 void BFS()
 53 {
 54     struct obj temp,temp2;
 55     int j;
 56
 57     temp.no=begin;//出发点入队
 58     temp.pre=-1;//出发点不考虑前驱节点
 59     q.push(temp);
 60     check[begin]=1;//标记出发点已经入队
 61     s[begin]=-1;
 62
 63     if(begin==end)
 64     {
 65         flag=1;
 66         return ;//出发点和终止点相同,可以直接返回了。
 67     }
 68
 69     while(!q.empty())//当队列不为空时继续搜过
 70     {
 71         temp=q.front();
 72          for(j=0;j<maxN;j++)//寻找temp节点的相邻节点,把相邻节点入队
 73         {
 74             if(p[temp.no][j]==1&&check[j]==0)//发现相邻节点j而且相邻节点j尚未入过队
 75             {
 76                 temp2.no=j;
 77                 temp2.pre=temp.no;
 78                 q.push(temp2);
 79                 check[j]=1;
 80                 s[j]=temp.no;
 81
 82                 if(j==end)
 83                 {
 84                     flag=1;//已经找到了终点end
 85                     break;
 86                 }
 87             }
 88         }
 89         q.pop();//队头出队
 90         if(flag==1)
 91         {
 92             break;
 93         }
 94     }
 95 }
 96 void print()
 97 {
 98     int i;
 99     printf("%c ",end+‘A‘);
100     for(i=end;i!=begin;)
101     {
102         //printf("%d ",a[i].no+1);//输出节点编号(编号1~n)
103         printf("%c ",s[i]+‘A‘);
104         i=s[i];
105     }
106     printf("\n");
107 }
时间: 2024-08-09 09:32:40

城市来往最短路线的相关文章

UVA 1600 Patrol Robot(机器人穿越障碍最短路线BFS)

UVA 1600 Patrol Robot Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Description A robot has to patrol around a rectangular area which is in a form of mxn grid (m rows and n columns). The rows are labeled from 1 to m. The colu

百度地图api文档实现任意两点之间的最短路线规划

两个点之间的路线是使用“Marker”点连接起来的,目前还没找到改变点颜色的方法,测试过使用setStyle没有效果. <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta name="viewport" content="initial-scale=1.0, user-sc

地铁最短路线个人项目

地铁个人项目 主要功能 编写一个程序实现北京地铁最短乘坐(站)线路查询,输入为起始站名和目的站名,输出为从起始站到目的站的最短乘坐站换乘线路. 数据输入格式 文件bgstations.txt为数据文件,包含了北京地铁的线路及车站信息.其格式如下: <地铁线路总条数> <线路1> <线路1站数> <站名1> <换乘状态> <站名2> <换乘状态> ... <线路2> <线路2站数> <站名1&g

BFS遍历所有最短路线

K - Caravans Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice URAL 2034 Description Student Ilya often skips his classes at the university. His friends criticize him for this, but they don’t know tha

UVA 1600 Patrol Robot(机器人穿越障碍最短路线BFS) 解题心得

原题: Description A robot has to patrol around a rectangular area which is in a form of mxn grid (m rows and n columns). The rows are labeled from 1 to m. The columns are labeled from 1 to n. A cell (i, j) denotes the cell in row i and column j in the

结对项目—地铁出行路线规划

结对项目—地铁出行路线规划 我的搭档:陈鸿超 14061216 https://github.com/ChengFR/PairProgramming_SubwayRoute- 会在十一期间发布新版本 结对编程体会: 结对编程的优点: 站在软件开发的角度,两个人共同面对同一台电脑进行开发,无论是效率还是软件质量都要超过一个人进行开发的情况. 对于还处于学习阶段的年轻软件开发者来说,结对编程是一个很好的互相学习的机会 结对编程时动力.责任感更强 结对编程的缺点: 对于我们来说,寻找两个人共同的时间进

[图论训练]BZOJ 3245: 最快路线【最短路】

Description 精 明的小R每每开车出行总是喜欢走最快路线,而不是最短路线.很明显,每条道路的限速是小R需要考虑的关键问题.不过有一些限速标志丢失了,于是小R将不知 道能开多快.不过有一个合理的方法是进入这段道路时不改变速度行驶.你的任务就是计算从小R家(0号路口)到D号路口的最快路线. 现在你得到了这个城市的地图,这个地图上的路都是单向的,而且对于两个路口A和B,最多只有一条道路从A到B.并且假设可以瞬间完成路口的转弯和加速. Input 第一行是三个整数N,M,D(路口数目,道路数目

bzoj3245 最快路线

Description 精明的小R每每开车出行总是喜欢走最快路线,而不是最短路线.很明显,每条道路的限速是小R需要考虑的关键问题.不过有一些限速标志丢失了,于是小R将不知道能开多快.不过有一个合理的方法是进入这段道路时不改变速度行驶.你的任务就是计算从小R家(0号路口)到D号路口的最快路线. 现在你得到了这个城市的地图,这个地图上的路都是单向的,而且对于两个路口A和B,最多只有一条道路从A到B.并且假设可以瞬间完成路口的转弯和加速. Input 第一行是三个整数N,M,D(路口数目,道路数目,和

华为内部员工测评题——地铁站最佳路线推荐

背景概述 ?城市的地铁网络由多条线路组成 ?每条线路上有多个车站,线路自身没有交叉点 ?线路间交叉或重叠时,共用车站,在这些车站上可相互换乘 ?每条线路都是双向行车 ?线路有两种:I形线和O形线 –I形线有两个端点,乘客在端点处只能乘坐开往另外一端的地铁,在非端点处则有两个方向可选择.(如图中8号线) –O形线所有车站形成环,没有端点,乘客在任一站都有两个方向可选择.(如图中4号线) 功能需求 在地铁网络中任选一站为起点,任选另一站为终点,中途可换乘,要求输出 1)最短路线长度:从起点到终点经过