最小生成树

代码:

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& parent, int x) {
if (parent[x] != x) {
parent[x] = find(parent, parent[x]);
}
return parent[x];
}

// 并查集合并函数
void unionSets(vector& parent, int x, int y) {
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& parent, int x) {
if (parent[x] != x) {
parent[x] = find(parent, parent[x]);
}
return parent[x];
}

void unionSets(vector& parent, int x, int y) {
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;
    }
}

}

posted @ 2025-06-24 16:44  YOLO霖  阅读(6)  评论(0)    收藏  举报