1. 最优乘车问题概述
最优乘车(travel)是信息学奥赛中的经典图论问题,源自《信息学奥赛一本通》P1377。该问题模拟了现实生活中的公交出行场景:给定若干条单向巴士线路和车站信息,要求计算从起点到终点的最少换乘次数。
这个问题的核心在于将公交网络抽象为图结构。每条巴士线路可以看作图中的一条路径,而车站则是图中的节点。由于巴士是单程行驶的,因此构建的是有向无权图。问题的特殊之处在于,我们需要计算的是"换乘次数"而非传统的最短路径。
提示:在实际解题中,很多选手容易混淆"乘车次数"和"换乘次数"。换乘次数指的是在不同线路之间切换的次数,比如从1路车换到2路车算一次换乘。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 问题建模与图论抽象
2.1 图的构建方法
对于最优乘车问题,我们需要将公交线路数据转化为图结构。具体构建方法如下:
- 将每个车站作为图中的一个顶点
- 对于每条巴士线路上的车站序列,从前到后建立有向边
- 边的权重统一设为1(因为只计算换乘次数)
例如,有一条巴士线路A→B→C→D,则建立边A→B、B→C、C→D。注意不建立A→C这样的"跳站"边,因为实际公交不允许这样乘车。
2.2 换乘次数的特殊处理
换乘次数的计算是本问题的关键。在图中,换乘发生在当乘客从一条线路的边切换到另一条线路的边时。为了在图中体现这一点,可以采用以下技巧:
- 如果在车站S需要换乘,意味着在S点从一条线路的边切换到另一条线路的边
- 因此,路径上的换乘次数等于路径中使用不同线路边的切换次数
实际操作中,可以通过给边添加线路标记,然后在遍历时统计线路变化次数来实现换乘计数。
3. 算法选择与实现
3.1 广度优先搜索(BFS)的应用
由于边权相同且需要找最少换乘次数,BFS是最合适的算法。具体实现步骤:
- 从起点站开始BFS遍历
- 维护一个距离数组dist[],记录到每个站点的换乘次数
- 对于当前站点的所有邻接站点,如果未被访问过,则更新其距离
- 使用队列管理待访问的站点
BFS的伪代码实现:
cpp复制queue<int> q;
vector<int> dist(N, INF);
dist[start] = 0;
q.push(start);
while(!q.empty()) {
int u =
