1. 题目理解与解题思路
这道题目来自CSP-J 2019江西赛区,考察的是图论中最短路径的应用。题目描述了一个由n座城市和m条双向道路组成的交通网络,每条道路通行时间均为1单位时间。我们需要在保证从首都(1号城市)到s1城市的最短时间不超过t1,同时到s2城市的最短时间不超过t2的前提下,尽可能多地拆除道路。
1.1 核心问题分析
这道题的关键在于理解"独立条件"的含义。题目要求的是:
- 从1到s1的最短路径≤t1
- 从1到s2的最短路径≤t2
这两个条件需要同时满足,但不需要路径之间有交集。也就是说,我们可以找到两条完全独立的路径分别满足这两个条件。
1.2 解题思路
我的解题思路分为以下几个步骤:
- 使用Dijkstra算法计算从首都1出发到所有城市的最短距离dis1
- 计算从s1出发到所有城市的最短距离diss1
- 计算从s2出发到所有城市的最短距离diss2
- 遍历所有城市i,检查dis1[i] + diss1[i] ≤ t1且dis1[i] + diss2[i] ≤ t2
- 对于满足条件的i,计算保留的道路数=dis1[i]+diss1[i]+diss2[i]
- 最大可拆除道路数=m-保留的道路数
注意:这里的关键是理解dis1[i]+diss1[i]表示从1→i→s1的路径长度,同理dis1[i]+diss2[i]表示从1→i→s2的路径长度。我们寻找的是这样一个中间点i,使得两条路径都满足时间限制。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 算法实现详解
2.1 数据结构选择
我选择使用邻接表来存储图结构,这是处理稀疏图(边数远小于完全图)的高效方式。具体实现如下:
cpp复制constexpr int N=3e3+1; // 最大城市数+1
vector<int> e[N]; // 邻接表存储图
对于3000个节点的图来说,邻接表既能节省空间,又能高效地进行遍历。
2.2 Dijkstra算法实现
Dijkstra算法是解决单源最短路径问题的经典算法,这里我使用了优先队列优化的版本:
cpp复制vector<int> dijkstra(int s){
vector<int> dis(n+1,0x3f3f3f3f); // 初始化距离为无穷大
