【大作业】城市地铁线路最短路规划及路径输出(满分) 您所在的位置:网站首页 乘坐地铁越来越方便翻译 【大作业】城市地铁线路最短路规划及路径输出(满分)

【大作业】城市地铁线路最短路规划及路径输出(满分)

2023-07-13 09:27| 来源: 网络整理| 查看: 265

4、地铁搭乘方案选择 轨道交通越来越发达,我们的出行也越来越方便。从学校门口的地铁站乘坐地铁可以到达很多地方。 计算地铁出行的最短路径,要求如下:(默认站点与站点之间权值为 1,也可以用时间或距离进行衡量) 1) 画出从西南石油大学出发,前往世纪城的地铁交通图,分析出哪条线路最短,详细说明分析思路。 2) 用算法实现你的分析思路,并输出最短路径。(包括代码和运行结果的截图) 3) 分析算法的性能,至少包括时间复杂度和空间复杂度等。

成都市地铁路线图可以看作是一个有环无向图。 根据老师提供的成都地铁路线图,我一共划分了5条可行路线,并沿途标记了56个站点,相当于无向图中的56个结点。 根据题目要求我将默认站点与站点之间权值为1。

下面是我使用 i p a d ipad ipad 画出的从西南石油大学出发,前往世纪城的地铁交通路线图。

在这里插入图片描述

1)思路分析

对于最短路问题,我这里使用 D i j k s t r a Dijkstra Dijkstra 算法来求得从石油大学站到世纪城站的最短路线并使用prev数组记录最短路径并最后输出所选择路线的站点英文名称。

1. 求得最短路径算法思路分析:

本题实际上可以简化为:

题目背景

由于疫情原因我们没办法开学啦,为了能让同学们不挂科,心善的老师决定布置大作业作为期末成绩的一部分啦

题目描述

一个有环无向图中,有n个结点和m条边,每条边的权值都是1,求得从起点s到终点t的最短路长度,并正序输出最短路径信息。

输入格式

第一行两个正整数,n和m,表示图的结点数和边数。 第二行到n+1行,为n个字符串,代表n个站点信息(中间可能带空格的英文站名) 。 第n+2行到n+2+m行,为三个正整数x,y,z,代表x和y之间连一条权值为z的无向边。

输出格式

首先输出最短路长度:以及最短路径长度。 然后正序输出最短路径上站点的编号和站名信息。

因此可以将各各站点构造n个点,m条边的数据直接使用 D i j k s t r a Dijkstra Dijkstra 算法即可求得最短路。 D i j k s t r a Dijkstra Dijkstra 算法,经典的最短路算法,基于贪心思想的,适用于非负权值图的时间复杂度为 Θ ( n 2 ) \Theta(n^2) Θ(n2)优秀算法。

优先队列优化思路:

由于 D i j k s t r a Dijkstra Dijkstra算法 Θ ( n 2 ) \Theta(n^2) Θ(n2)的算法瓶颈是每次查找dis数组的最小的值,我们可以使用STL中的优先队列优化这一操作,将 Θ ( n ) \Theta(n) Θ(n)的查找优化至 O ( l o g n ) O(logn) O(logn)

但是我作为一名我校优秀的 ACMer 只是使用优先队列怎么行,我决定再进行一些优化(因为优先队列还是太慢啦),考虑如果要优化 D i j k s t r a Dijkstra Dijkstra算法,那么就要摒弃落后的优先队列,由于只需要借用优先队列寻找最小值操作,而优秀的线段树完全可以代替实现。因此我决定补充一个线段树优化版本的 D i j k s t r a Dijkstra Dijkstra。

线段树优化思路:

具体思路如下: D i j k s t r a Dijkstra Dijkstra算法的核心思想就是每次取出最小的 d i s [ i ] , i ϵ [ 1 , n ] dis[i],i\epsilon[1,n] dis[i],iϵ[1,n] 且当前的结点i并未被访问过。因此我们使用线段树来全程模拟这个操作。我们用线段树维护区间最小值。每次取出区间 [ 1 , n ] [1,n] [1,n] 中 d i s dis dis最小的点,作为当前节点。根据 D i j k s t r a Dijkstra Dijkstra的设计思想,当前节点的 d i s dis dis已经是最小的了,所以遍历该点能到达的所有子结点,更新子结点的 d i s dis dis,然后由于普通的线段树不支持删除操作(可持久化线段树支持,这里就不展开了)因此直接在线段树中把当前节点位置的值改成 + ∞ +∞ +∞即可(模拟将该点删除)。

二者的理想时间复杂度虽然相同,都是 Θ ( n l o g m ) \Theta(nlogm) Θ(nlogm),但是线段树的常数更小,一般运行起来时间会是优先队列的 1 2 \frac{1}{2} 21​!(至于我是怎么得到这个结论的,请看文末)

2. 输出最短路径思路分析:

我这里使用一个 p r e v [ j ] prev[ j ] prev[j]来记录最短路上顶点 j 的前驱,可以在 Θ ( V ) \Theta(V) Θ(V)的时间内完成最短路径的恢复(V是边数)。在 d [ j ] d[ j ] d[j]被 d [ j ] = d [ k ] + c o s t [ k ] [ j ] d[ j ] = d[ k ] + cost[ k ][ j ] d[j]=d[k]+cost[k][j]更新时,修改 p r e v [ j ] = k prev[ j ] = k prev[j]=k,这样就可以求出来 p r e v prev prev的数组,可以在以上算法中用路径前驱标记法来还原出来路径。

为了输出站点名称,我使用56个int型整数代表56个沿途可能经过的站点。使用map来存储站点信息(英文名)。

2)代码实现 1.数据

本次5条路线一共56个站点(结点)

通过百度百科查找成都市地铁信息梳理得到下面我所需要用到的站点列表:

地铁三号线站点信息 结点1~23

起点:石油大学站 Southwest Petroleum University 钟楼站 Clock Tower 马超西路站 Machao Road West 团结新区站 Tuanjiexinqu 锦水河站 Jinshuihe 三河场站 Sanhechang 金华寺东路站 Jinhua Temple Road East 植物园站 Botanical Garden 一期工程 军区总医院站 Chengdu Junqu General Hospital 熊猫大道站 Panda Avenue 动物园站 Chengdu Zoo 昭觉寺南路站 Zhaojuesi Road South 驷马桥站 Simaqiao 李家沱站 Lijiatuo 前锋路站 Qianfeng Road 红星桥站 Hongxing Bridge 市二医院站 Chengdu Second People’s Hospital 春熙路站 Chunxi Road 新南门站 Xinnanmen 磨子桥站 Moziqiao 省体育馆站 Sichuan Gymnasium 衣冠庙站 Yiguanmiao 高升桥站 Gaoshengqiao

地铁一号线站点信息: 结点:24~31

倪家桥站 Nijiaqiao 桐梓林站 Tongzilin 火车南站 South Railway Station 高新站 Hi-Tech Zone 金融城站 Financial City 孵化园站 Incubation Park 锦城广场站 Jincheng Plaza

终点:世纪城站 Century City

地铁一号线站点信息: 结点:32~37

人民北路站 North Renmin Road 文殊院站 Wenshu Monastery 骡马市站 Luomashi 天府广场站 Tianfu Square 锦江宾馆站 Jinjiang Hotel 华西坝站 Huaxiba

地铁二号线站点信息: 结点:38~39

牛王庙站 Niuwangmiao 东门大桥站 Dongmen Bridge

地铁六号线站点信息: 结点:40~46

顺江路站 Shunjiang Road 三官堂站 Sanguantang 东光站 Dongguang 琉璃场站 Liulichang 琉三路站 Liusan Road 金石路站 Jinshi Road 金融城东站 East Financial City

地铁九号线站点信息: 结点:47

心岛站 Xindao

地铁五号线站点信息: 结点:48~56

西北桥站Xibeiqiao 花牌坊站Huapaifang 抚琴站Fuqin 中医大省医院站Chengdu University of TCM &Sichuan Provincial People’s Hospital 青羊宫站Qingyang Taoist Temple 省骨科医院站Sichuan Provincial Orthopaedic Hospital 科园站Keyuan 九兴大道站Jiuxing Avenue 神仙树站Shenxianshu

梳理完56个结点有了这些信息以后就可以建图了!

然后手动造数据: 一共56个结点与结点信息(站名)和60条无向边

最后整张地铁图的数据及最后的测试数据如下:

输入格式

第一行两个正整数,n和m,表示图的结点数和边数。 第二行到n+1行,为n个字符串,代表n个站点信息(中间可能带空格的英文站名) 。 第n+2行到n+2+m行,为三个正整数x,y,z,代表x和y之间连一条权值为z的无向边。

输出格式

首先输出最短路长度:以及最短路径长度。 然后正序输出最短路径上站点的编号和站名信息。 样例:

56 60 Southwest Petroleum University Clock Tower Machao Road West Tuanjiexinqu Jinshuihe Sanhechang Jinhua Temple Road East Botanical Garden Chengdu Junqu General Hospital Panda Avenue Chengdu Zoo Zhaojuesi Road South Simaqiao Lijiatuo Qianfeng Road Hongxing Bridge Chengdu Second People's Hospital Chunxi Road Xinnanmen Moziqiao Sichuan Gymnasium Yiguanmiao Gaoshengqiao Nijiaqiao Tongzilin South Railway Station Hi-Tech Zone Financial City Incubation Park Jincheng Plaza Century City North Renmin Road Wenshu Monastery Luomashi Tianfu Square Jinjiang Hotel Huaxiba Niuwangmiao Dongmen Bridge Shunjiang Road Sanguantang Dongguang Liulichang Liusan Road Jinshi Road East Financial City Xindao Xibeiqiao Huapaifang Fuqin Chengdu University of TCM &Sichuan Provincial People’s Hospital Qingyang Taoist Temple Sichuan Provincial Orthopaedic Hospital Keyuan Jiuxing Avenue Shenxianshu 1 2 1 2 3 1 3 4 1 4 5 1 5 6 1 6 7 1 7 8 1 8 9 1 9 10 1 10 11 1 11 12 1 12 13 1 13 14 1 14 15 1 15 16 1 16 17 1 17 18 1 18 19 1 19 20 1 20 21 1 15 32 1 18 35 1 32 33 1 33 34 1 34 35 1 35 36 1 36 37 1 37 21 1 32 48 1 48 49 1 49 50 1 50 51 1 51 52 1 52 53 1 53 23 1 23 22 1 22 21 1 23 54 1 54 55 1 55 56 1 56 26 1 21 24 1 24 25 1 25 26 1 26 27 1 27 28 1 28 29 1 29 30 1 30 31 1 18 39 1 39 38 1 38 40 1 40 41 1 41 42 1 42 43 1 43 44 1 44 45 1 45 46 1 46 47 1 47 29 1 2.优先队列优化版本程序 #include #include #include #include #include #include #define ls (p int x = 0, f = 1, ch = getchar(); while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();} while(isdigit(ch)) x = (x over(i,1,n)dis[i]=INF; memset(vis,false,sizeof vis); q.push(make_pair(0,st)); dis[st]=0; while(!q.empty()) { int u=q.top().second; q.pop(); if(vis[u])continue; vis[u]=true; for(int i=head[u];i;i=edge[i].nex) { int v=edge[i].v; if(dis[u]+edge[i].val for(int i=ed;i;i=pre[i]) pa[++tot]=i; cout getline(cin,str); mp[i] = str; } over(i,1,m){ int x,y,z; x = read(),y = read(),z = read(); add(x,y,z);add(y,x,z); } dijkstra(); print(); return 0; } 3.线段树优化版本程序 #include #include #include #include #include #include #define over(i,s,t) for(int i=s;i=s;--i) using namespace std; typedef long long ll; const int N=1e3+7; const int inf=1e9+7; const int mod=2147483647; const double EPS=1e-6; mapmp; int read() { int x = 0, f = 1, ch = getchar(); while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();} while(isdigit(ch)) x = (x } edge(int t, int ww, int nn) {to = t, w = ww, nxt = nn;} }e[N ll dis; int x; node() {} node(ll d, int xx) {dis = d, x = xx;} }dis[N dis[p].x = l; return;} int mid = l + r >> 1; build(p dis[p].dis = y; return;} int mid = l + r >> 1; if(x return dis[p];} int mid = l + r >> 1; node ans = node(inf, 0), tmp; if(ls for(int k = 1; k register int v = e[i].to; if(ans[u] + e[i].w for(int i=ed;i;i=pre[i]) pa[++tot]=i; cout getline(cin,str); mp[i] = str; } for(int u, v, w, i = 1; i


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有