图的最小生成树 Kruskal算法 C++实现

/*
* File name  : cmst01.cpp
* Function   : 图的最小生成树 Kruskal算法  C++实现
* Created on : 2016年6月8日
* Author     : beijiwei@qq.com
* Copyright  : 欢迎大家和我一起交流学习,转载请保持源文件的完整性。
任何单位和个人不经本人允许不得用于商业用途

input:
6 9
2 4 11
3 5 13
4 6 3
5 6 4
2 3 6
4 5 7
1 2 1
3 4 9
1 3 2


*/
#include <cstdio>
#include <iostream>
#pragma warning(disable:4996)

using namespace std;

typedef struct edge{
    int start;
    int end;
    int weight;
}Edge;

#define M 20

Edge edge_map[M];
int path[M];

int boss[M];
int get_boss(int x);
int join(int x, int y);

int main(int argc, char** argv)
{
    freopen("input.txt", "r", stdin);
    int vertex_num, edge_num;
    cin >> vertex_num>>edge_num;

    for (int i = 1; i <= edge_num; i++)//读入边的信息
    {
        cin >> edge_map[i].start >> edge_map[i].end >> edge_map[i].weight;
    }
    for (int i = 1; i <= edge_num; i++)// 对边进行 按权值 作升序排序, 选择排序
    {
        int k = 1;
        Edge tmp;
        for (int j = i+1; j <= edge_num; j++)
        {
            if (edge_map[k].weight > edge_map[j].weight)
            {
                k = j;
            }
        }
        tmp = edge_map[i];
        edge_map[i] = edge_map[k];
        edge_map[k] = tmp;
    }
    //初始化并查集
    for (int i = 1; i <= vertex_num; i++)
    {
        boss[i] = i;
    }
    int edge_count = 0, weight_sum=0;
    for (int i = 1; i <= edge_num; i++)
    {
        if (join(edge_map[i].start, edge_map[i].end) == 1)// 如果 这条边的两个顶点 尚未联通,则选用这条边
        {
            path[edge_count] = i;
            edge_count++;
            weight_sum += edge_map[i].weight;
            
        }
        if (edge_count == vertex_num - 1)
        {
            break;
        }
    }

    cout << "最短路径是: " << weight_sum << endl;
    for (int i = 0; i < edge_count; i++)
    {
        cout << "边的起点,终点,权值分别是: " << edge_map[path[i]].start << " , " << edge_map[path[i]].end << " , " << edge_map[path[i]].weight << endl;
    }

    return 0;
}

int get_boss(int x)
{
    int tmp;
    if (boss[x] == x)
    {
        tmp= x;
    }
    else{
        tmp = get_boss(boss[x]);
        boss[x] = tmp;
    }
    return tmp;
}
int join(int x, int y)
{
    int bossx, bossy;
    bossx = get_boss(x);
    bossy = get_boss(y);

    if (bossx != bossy)
    {
        boss[bossy] = bossx;
        get_boss(y);
        return 1;// 不在同一个集合中
    }
    return 0;// 在同一个集合中
}

最小生成树Kruskal算法是一种常用的算法,用于找到一个连通最小生成树。下面是Kruskal算法C++代码示例: ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; // 定义边的结构体 struct Edge { int src, dest, weight; }; // 定义并查集的数据结构 classFind { public: vector<int> parent, rank; UnionFind(int n) { parent.resize(n); rank.resize(n); for (int i = 0; i < n; i++) { parent[i] = i; rank[i] = 0; } } int find(int x) { if (parent[x] != x) { parent[x] = find(parent[x]); } return parent[x]; } void unionSet(int x, int y { int rootX = find(x); int rootY = find(y); if (rootX != rootY) { if (rank[rootX] < rank[rootY]) { parent[rootX] = rootY; } else if (rank[rootX] > rank[rootY]) { parent[rootY] = rootX; } else { parent[rootY] = rootX; rank[rootX]++; } } } }; // Kruskal算法实现 vector<Edge> kruskalMST(vector<Edge>& edges, int V) { // 按照边的权重进行排序 sort(edges.begin(), edges.end(), [](const Edge& a, const Edge& b) { return a.weight < b.weight; }); vector<Edge> result; UnionFind uf(V); for (const Edge& edge : edges) { int src = edge.src; int dest = edge.dest; // 判断加入边后是否形成环路 if (uf.find(src) != uf.find(dest)) { uf.unionSet(src, dest); result.push_back(edge); } } return result; } int main() { int V, E; cout << "请输入顶点数和边数:"; cin >> V >> E; vector<Edge> edges(E); cout << "请输入每条边的起点、终点和权重:" << endl; for (int i = 0; i < E; i++) { cin >> edges[i].src >> edges[i].dest >> edges[i].weight; } vector<Edge> mst = kruskalMST(edges, V); cout << "最小生成树的边:" << endl; for (const Edge& edge : mst) { cout << edge.src << " - " << edge.dest << " : " << edge.weight << endl; } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值