C DFS+最短路径+邻接表表示+地铁换乘(map保存地铁线路) 1131 Subway Map (30分)

该博客介绍了一种使用深度优先搜索(DFS)解决寻找地铁线路中最短路径的方法。通过构建邻接表来表示地铁线路,并用动态数组记录每个车站的相邻站点。利用字典存储线路信息,并在DFS过程中计算最小换乘次数。博客提供了详细步骤,从读入数据到输出最短路径及换乘信息,特别强调了如何处理换乘次数的计算和路径存储。
摘要由CSDN通过智能技术生成

1131 Subway Map (30分)

In the big cities, the subway systems always look so complex to the visitors. To give you some sense, the following figure shows the map of Beijing subway. Now you are supposed to help people with your computer skills! Given the starting position of your user, your task is to find the quickest way to his/her destination.
在这里插入图片描述
subwaymap.jpg

Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤ 100), the number of subway lines. Then N lines follow, with the i-th (i=1,⋯,N) line describes the i-th subway line in the format:

M S[1] S[2] … S[M]

where M (≤ 100) is the number of stops, and S[i]'s (i=1,⋯,M) are the indices of the stations (the indices are 4-digit numbers from 0000 to 9999) along the line. It is guaranteed that the stations are given in the correct order – that is, the train travels between S[i] and S[i+1] (i=1,⋯,M−1) without any stop.

Note: It is possible to have loops, but not self-loop (no train starts from S and stops at S without passing through another station). Each station interval belongs to a unique subway line. Although the lines may cross each other at some stations (so called “transfer stations”), no station can be the conjunction of more than 5 lines.

After the description of the subway, another positive integer K (≤ 10) is given. Then K lines follow, each gives a query from your user: the two indices as the starting station and the destination, respectively.

The following figure shows the sample map.
在这里插入图片描述
samplemap.jpg

Note: It is guaranteed that all the stations are reachable, and all the queries consist of legal station numbers.

Output Specification:
For each query, first print in a line the minimum number of stops. Then you are supposed to show the optimal path in a friendly format as the following:

Take Line#X1 from S1 to S2.
Take Line#X2 from S2 to S3.

where Xi’s are the line numbers and Si’s are the station indices. Note: Besides the starting and ending stations, only the transfer stations shall be printed.

If the quickest path is not unique, output the one with the minimum number of transfers, which is guaranteed to be unique.

Sample Input:

4
7 1001 3212 1003 1204 1005 1306 7797
9 9988 2333 1204 2006 2005 2004 2003 2302 2001
13 3011 3812 3013 3001 1306 3003 2333 3066 3212 3008 2302 3010 3011
4 6666 8432 4011 1306
3
3011 3013
6666 2001
2004 3001

Sample Output:

2
Take Line#3 from 3011 to 3013.
10
Take Line#4 from 6666 to 1306.
Take Line#3 from 1306 to 2302.
Take Line#2 from 2302 to 2001.
6
Take Line#2 from 2004 to 1204.
Take Line#1 from 1204 to 1306.
Take Line#3 from 1306 to 3001.

解题
输入样例为每条线的站数;
图结点为站;边为站与站之间的路径;
有些结点有多条边,有些结点只有前后两条边;头尾结点只有一条边;
稀疏图用邻接表表示;

#include<iostream>
#include<algorithm>
#include<vector>
#include<unordered_map>
using namespace std;
#define MaxN 101 
#define inf 0xfffffff

读入地铁线路
构建二维动态数组vector<vector> station,大小定义为10000(因为站台号<9999);
station[i]中存放i结点直接相连的结点

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Dijkstra算法是解决单源最短路径问题的一种经典算法,其基本思想是利用贪心的思想,每次选取未确定最短路径的节点中距离起点最近的节点,然后根据该节点更新与该节点相邻的节点的距离。具体实现可以采用邻接表或邻接矩阵来表示图,同时利用优先队列STL来维护节点距离的更新。 算法步骤如下: 1.初始化:将起点的距离设置为0,其余节点的距离设置为无穷大,将所有节点标记为未确定最短路径。 2.选择当前距离起点最近的未确定最短路径节点,将其标记为确定最短路径,并更新其相邻节点的距离。 3.重复步骤2直到终点被标记为确定最短路径或者所有节点均被标记为确定最短路径。 4.输出最短路径。 使用邻接表可以较为简便地实现Dijkstra算法,具体实现如下: ```c++ #include<bits/stdc++.h> using namespace std; const int MAXN=100010; const int INF=0x3f3f3f3f; struct Edge{ int to,w; }; vector<Edge> G[MAXN]; int dis[MAXN]; bool vis[MAXN]; void dijkstra(int s){ priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> q; memset(dis,INF,sizeof(dis)); memset(vis,false,sizeof(vis)); dis[s]=0; q.push(make_pair(0,s)); while(!q.empty()){ int u=q.top().second; q.pop(); if(vis[u]) continue; vis[u]=true; for(int i=0;i<G[u].size();i++){ int v=G[u][i].to; int w=G[u][i].w; if(dis[v]>dis[u]+w){ dis[v]=dis[u]+w; q.push(make_pair(dis[v],v)); } } } } int main(){ int n,m,s,t; scanf("%d%d%d%d",&n,&m,&s,&t); for(int i=1;i<=m;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); G[u].push_back((Edge){v,w}); G[v].push_back((Edge){u,w}); } dijkstra(s); printf("%d\n",dis[t]); return 0; } ``` 其中,邻接表G[u]表示节点u的相邻节点,Edge结构体表示边的信息,dis[u]表示起点到节点u的最短路径长度,vis[u]表示节点u是否被标记为确定最短路径。使用优先队列STL来维护节点距离的更新,pair<int,int>表示节点距离和节点编号,greater<pair<int,int>>表示节点距离的比较器,使得距离小的节点在队列前面。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值