最小生成树的Kruskal算法(C/C++)--附有测试数据和结果

算法原理:将图G 中的边按权数从小到大逐条考察,
     按不构成圈的原则加入到T中(若有选择时, 不同的选
     择可能会导致最后生成树的权数不同), 直到
     q(T) = p(G)-1为止, 即 T 的边数 = G 的顶点1 为止.
算法中无圈性的判定比较麻烦,应该用标记法最好,对各个分支的顶点标号。
参考书:2004,《图论及其应用》,科学出版社,孙惠泉 编著。

#include<iostream>
#include<fstream>
#define N 100
using namespace std;
int n;//结点数
int a[N][N] = {0};
bool judgeNode(int flagNodes[N]){//判断是否还有未访问结点
    for(int i = 0; i < n; i++)
        if(flagNodes[i] == 0) return 1;
    return 0;
}
void judgeSub(int flagSub[N], int x, int y){//标记分支
    if(flagSub[x] != 0){
        if(flagSub[y] == 0) flagSub[y] = flagSub[x];
        else{
            int min = flagSub[x] < flagSub[y] ? flagSub[x] : flagSub[y];
            int max = flagSub[x] + flagSub[y] - min;
            for(int i = 0; i < n; i++)
                if(flagSub[i] == max)
    
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是使用C++实现Kruskal算法最小生成树的示例代码: ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; // 定义边的结构体 struct Edge { int src, dest, weight; }; // 定义并查集的数据结构 struct DisjointSet { int *parent, *rank; int n; DisjointSet(int n) { this->n = n; parent = new int[n]; rank = new int[n]; // 初始化每个节点的父节点为自身,秩为0 for (int i = 0; i < n; i++) { parent[i] = i; rank[i] = 0; } } // 查找节点的根节点 int find(int u) { if (u != parent[u]) { parent[u] = find(parent[u]); } return parent[u]; } // 合并两个集合 void merge(int x, int y) { int rootX = find(x); int rootY = find(y); if (rank[rootX] < rank[rootY]) { parent[rootX] = rootY; } else if (rank[rootX] > rank[rootY]) { parent[rootY] = rootX; } else { parent[rootY] = rootX; rank[rootX]++; } } }; // Kruskal算法最小生成树 void kruskal(vector<Edge>& edges, int n) { // 按照边的权重进行排序 sort(edges.begin(), edges.end(), [](const Edge& a, const Edge& b) { return a.weight < b.weight; }); vector<Edge> result; // 存储最小生成树的边 DisjointSet ds(n); for (const auto& edge : edges) { int src = edge.src; int dest = edge.dest; // 判断两个节点是否在同一个集合中 if (ds.find(src) != ds.find(dest)) { result.push_back(edge); ds.merge(src, dest); } } // 输出最小生成树的顶点集合和边的集合 cout << "顶点集合:"; for (int i = 0; i < n; i++) { cout << i << " "; } cout << endl; cout << "边的集合:"; for (const auto& edge : result) { cout << "(" << edge.src << ", " << edge.dest << ") "; } cout << endl; } int main() { int n = 6; // 图的顶点数 // 定义图的边集合 vector<Edge> edges = { {0, 1, 4}, {0, 2, 3}, {1, 2, 1}, {1, 3, 2}, {2, 3, 4}, {3, 4, 2}, {4, 5, 6} }; kruskal(edges, n); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值