1. 题目背景与理解
这道GESP七级真题"城市规划"考察的是图论中的最小生成树算法应用。题目描述了一个典型的城市道路连通问题:A国有n座城市,通过m条双向道路连接,要求我们找到一种最优的修路方案。
在实际工程中,这类问题非常常见。比如市政部门需要规划城市间的道路网络,既要保证所有城市互相可达,又要尽可能降低建设成本。这正是最小生成树算法的经典应用场景。
注意:题目中明确所有城市原本就是连通的(即任意两城市间已有路径),这与现实中的某些情况不同。这意味着我们不需要考虑图不连通的情况。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 算法选择与思路分析
2.1 为什么选择Kruskal算法
对于这类问题,通常有两种主流解法:
- Prim算法 - 适合稠密图(边数接近完全图)
- Kruskal算法 - 适合稀疏图(边数远少于完全图)
在本题中,城市数量n和道路数量m的关系没有明确说明,但考虑到:
- 城市间道路通常不会太多(现实中的城市连接数有限)
- Kruskal算法实现更简单直观
- 题目要求输出具体选择的道路,Kruskal更容易记录边
因此我选择使用Kruskal算法来解决这个问题。
2.2 Kruskal算法核心思想
Kruskal算法的核心步骤是:
- 将所有边按权值从小到大排序
- 初始化一个空集合用于存放选中的边
- 按顺序考虑每条边,如果不形成环就加入集合
- 重复直到选中n-1条边
这里的关键是"不形成环"的判断,这可以通过并查集(Disjoint Set)数据结构高效实现。
3. 代码实现详解
3.1 数据结构设计
首先我们需要定义合适的数据结构:
cpp复制#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Edge {
int u, v, w;
Edge(int _u, int _v, int _w): u(_u), v(_v), w(_w) {}
};
vector<Edge> edges; // 存储所有边
vector<int> parent; // 并查集父节点数组
vector<Edge> selected; // 选中的边
