1. 问题背景与核心需求
最优乘车问题源自信息学奥赛经典教材《信息学奥赛一本通》中的P1377例题,是图论在实际交通场景中的典型应用。题目模拟了城市公交系统的换乘场景:给定若干条单向巴士线路(每条线路包含多个连续站点),要求计算从起点站到终点站的最少换乘次数。
这个问题的现实意义非常明显——我们每天乘坐公共交通时都在潜意识求解类似问题。比如从家到公司,如何选择巴士线路组合才能最小化换乘次数?手动计算在简单路网中尚可应付,但对于拥有几十条线路、数百个站点的大城市公交系统,就需要借助算法高效求解。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 图论建模思路解析
2.1 基础建模方法
常规的公交线路建模会直接将站点作为顶点,相邻站点间的移动作为边。但这种建模方式在计算换乘次数时存在明显缺陷——无法区分"同线路连续乘坐"和"跨线路换乘"这两种操作。
更合理的建模方式是将"乘坐特定线路到达某站点"作为图中的一个状态。具体实现时:
- 顶点:二元组(线路ID,站点ID)
- 边:分为两种类型
- 同线路移动:当站点A和B在同一条线路上且相邻时,建立权值为0的边(表示无需换乘)
- 跨线路换乘:当不同线路在同一个站点交汇时,建立权值为1的边(表示需要换乘)
2.2 优化建模方案
上述方法虽然准确但顶点规模过大。更高效的建模方式是:
- 将所有站点作为顶点
- 同一线路上的连续站点建立权值为0的边(表示可免费乘坐)
- 对每个站点,建立到该站点所有可达线路的反向边,权值为1(表示需要换乘)
这样处理后,从起点到终点的最短路径长度-1就是最少换乘次数。例如:
- 路径长度为1:直达,换乘0次
- 路径长度为3:换乘2次
3. 算法实现细节
3.1 数据结构选择
使用邻接表存储图结构更节省空间:
cpp复制struct Edge {
int to;
int cost; // 0表示同线路移动,1表示换乘
};
vector<vector<Edge>> graph;
输入处理时需要特别注意:
- 每条线路的站点序列是单向的
- 同一线路的站点编号需要建立连续边
- 不同线路的相同站点需要建立换乘边
3.2 最短路径算法选择
由于边权只有0和1两种,可以采用双端队列BFS(0-1 BFS)算法,时间复杂度O(
