1. 问题背景与核心需求
这道题目描述了一个典型的城市规划问题:给定平面上N个城市的坐标,需要修建公路将所有城市连通。题目给出的修建规则看似复杂,但经过分析可以发现其本质是求一个完全图的最小生成树(Minimum Spanning Tree, MST)。
在实际工程应用中,这类问题非常常见。比如在电网架设、通信基站建设、输油管道规划等场景中,我们都需要在保证所有节点连通的前提下,最小化总建设成本。这道题目正是这类实际问题的抽象表达。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 算法选择与复杂度分析
2.1 最小生成树算法对比
对于最小生成树问题,主要有两种经典算法:
-
Kruskal算法:
- 时间复杂度:O(E log E),其中E是边数
- 空间复杂度:O(E)
- 特点:需要对所有边进行排序,适合稀疏图
-
Prim算法:
- 朴素实现:O(V²)
- 堆优化实现:O(E log V)
- 特点:适合稠密图,特别是完全图
2.2 本题的特殊性分析
本题的特殊性在于:
- 这是一个完全图,边数E=V*(V-1)/2≈1.25×10⁷(当V=5000时)
- 题目给出的城市数量上限是5000
如果使用Kruskal算法:
- 需要存储约1.25×10⁷条边,内存消耗巨大(约200MB)
- 排序这些边的时间复杂度约为3×10⁸次操作,容易超时
而使用朴素Prim算法:
- 时间复杂度O(V²)=2.5×10⁷次操作
- 只需要存储V个点的坐标和距离信息,内存消耗极小
提示:在竞赛编程中,通常认为C++每秒可以处理约10⁷次简单操作。因此Prim算法的时间复杂度在合理范围内,而Kruskal算法则存在较大风险。
3. Prim算法实现细节
3.1 隐式图策略
由于完全图的边数太多,我们采用"隐式图"策略,即在需要计算两点距离时实时计算,而不是预先存储所有边。这种方法可以大幅节省内存。
距离计算公式:
code复制distance = sqrt((x1-x2)² + (y1-y2)²)
3.2 算法流程详解
-
初始化:
- 设置所有点到生成树的距离为无穷大(INF)
- 选择任意一个点作为起点,将其距离设为0
-
主循环
