最小生成树——kruskal算法

Kruskal算法是依次选择连接图中两个顶点间权值最小的边来实现的,当所选的边产生圈时就放弃选取该边,算法首先要将所有边的权值从小到大进行排序。

#include <string>
#include <iostream>
#include <algorithm>
using namespace std;

int sum;

typedef struct
{
    int row, col, val;
} matrix;

typedef struct
{
    string *vertexs; // 存储顶点
    matrix *edges; // 存储边
    int vertex, edge;
} adjmatrix;

void init_graph(adjmatrix & g, int vertex, int edge)
{
    g.vertex = vertex;
    g.edge = edge;
    g.vertexs = new string[g.vertex];
    g.edges = new matrix[g.edge];
}

void destroy_graph(adjmatrix & g)
{
    delete [] g.vertexs;
    delete [] g.edges;
}

bool cmp(const matrix & a, const matrix & b)
{
    return a.val < b.val;
}

void create_graph(adjmatrix & g)
{
    cout << "Enter vertex in graph:" << endl;
    for (int i = 0; i < g.vertex; i++) {
        cin >> g.vertexs[i];
    }
    int x, y, weight;
    cout << "Enter A to B and weight in graph:" << endl;
    for (int i = 0; i < g.edge; i++) {
        cin >> x >> y >> weight;
        g.edges[i].row = x;
        g.edges[i].col = y;
        g.edges[i].val = weight;
    }
}

int find_set(int *s, int x)
{
    while (s[x] >= 0) {
        x = s[x];
    }
    return x;
}

void union_set(int *s, int x, int y)
{
    s[x] = y;
}

void kruskal(adjmatrix & g)
{
    sort(g.edges, g.edges + g.edge, cmp);
    for (int i = 0; i < g.edge; i++) {
        cout << "(" << g.edges[i].row << ", " << g.edges[i].col << ") " << g.edges[i].val << endl;
    }
    int *s = new int[g.vertex];
    for (int i = 0; i < g.vertex; i++) {
        s[i] = -1;
    }
    int i = 0, count = 0;
    int x, y;
    int p1, p2;
    while (1) {
        x = g.edges[i].row;
        y = g.edges[i].col;
        p1 = find_set(s, x);
        p2 = find_set(s, y);
        if (p1 != p2) {
            count++;
            cout << "(" << g.vertexs[x] << ", " << g.vertexs[y] << "):" << g.edges[i].val << endl;
            sum += g.edges[i].val;
            union_set(s, p1, p2);
            if (count == g.vertex - 1) {
                break;
            }
        }
        i++;
    }
}

int main()
{
    int vertex, edge;
    cout << "Enter the number of vertex and edge of graph:" << endl;
    cin >> vertex >> edge;
    adjmatrix g;
    init_graph(g, vertex, edge);
    create_graph(g);
    kruskal(g);
    destroy_graph(g);
    cout << "The total value of the spanning tree is " << sum << endl;
    return 0;
}

参考:https://www.bilibili.com/video/BV1Xa4y1i7wu

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值