最小生成树
代码:
include
include
include
using namespace std;
struct Edge {
int u, v, weight;
// 重载小于运算符,用于边的排序
bool operator<(const Edge& other) const {
return weight < other.weight;
}
};
// 并查集查找函数,带路径压缩
int find(vector
if (parent[x] != x) {
parent[x] = find(parent, parent[x]);
}
return parent[x];
}
// 并查集合并函数
void unionSets(vector
parent[find(parent, x)] = find(parent, y);
}
int main() {
int n;
cin >> n;
vector<Edge> edges;
// 读取村庄间距离并构建边
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
int dist;
cin >> dist;
if (i < j) { // 避免重复添加边
edges.push_back({i, j, dist});
}
}
}
// 按边的权重排序
sort(edges.begin(), edges.end());
// 初始化并查集
vector<int> parent(n + 1);
for (int i = 1; i <= n; i++) {
parent[i] = i;
}
int q;
cin >> q;
// 处理已有道路
for (int i = 0; i < q; i++) {
int a, b;
cin >> a >> b;
unionSets(parent, a, b);
}
int totalLength = 0;
int edgesAdded = 0;
// 构建最小生成树
for (const Edge& edge : edges) {
int rootU = find(parent, edge.u);
int rootV = find(parent, edge.v);
if (rootU != rootV) {
unionSets(parent, rootU, rootV);
totalLength += edge.weight;
edgesAdded++;
if (edgesAdded == n - 1) {
break;
}
}
}
cout << totalLength << endl;
return 0;
}
1首先要定义数据结构
数据结构设计
cpp
运行
struct Edge {
int u, v, weight;
bool operator<(const Edge& other) const {
return weight < other.weight;
}
};
Edge 结构体表示图中的一条边,包含两个端点 u 和 v,以及边的权重 weight
重载 < 运算符用于后续边的排序,按权重升序排列
2查并函数定义
并查集(Union-Find)实现
cpp
运行
int find(vector
if (parent[x] != x) {
parent[x] = find(parent, parent[x]);
}
return parent[x];
}
void unionSets(vector
parent[find(parent, x)] = find(parent, y);
}
并查集是处理不相交集合合并与查询问题的高效数据结构
find 函数实现路径压缩,查找元素所在集合的根节点
unionSets 函数合并两个集合,将一个集合的根节点指向另一个集合的根节点
3核心:
int totalLength = 0;
int edgesAdded = 0;
for (const Edge& edge : edges) {
int rootU = find(parent, edge.u);
int rootV = find(parent, edge.v);
if (rootU != rootV) {
unionSets(parent, rootU, rootV);
totalLength += edge.weight;
edgesAdded++;
if (edgesAdded == n - 1) {
break;
}
}
}

浙公网安备 33010602011771号