数据结构-带权无向图-最小生成树(克鲁斯卡尔算法)

 本文采用kruskal法解决求最小生成树的各边权值和(从边集出发对各边按权值排序(冒泡排序)),排序也可以采用更高效的快排。

Description

根据输入构建无向带权图,并利用kruskal法求出最小生成树,输出该最小生成树的各边权值和。

输入:

第一行为:结点数; 第二行为各结点名;第三行为各边的权值。

输出:最小生成树的各边权值和。

 

Sample Input

5

A B C D E

A B 10

A C 8

A E 3

B C 2

B D 5

C E 7

D E 4

Sample Output

14

Hint

输出有换行符。

#include <bits/stdc++.h>
#define Maxnum 1005
#define Maxint 32767
using namespace std;
//邻接表的存储结构
typedef struct Arcnode
{
    int adjvex;
};
typedef struct Vnode
{
    char data;
} Vnode, Adjlist[Maxnum];
typedef struct edgenode
{ // 边集存储结构
    int vex1, vex2;
    int info;//权值
} edgenode;
typedef struct
{
    edgenode *edgelist;//边集组
    int edgenum;//边数
    Adjlist verices;
    int vex, arc;
} ALG;
int locatevex(ALG G, char v)
{//查找下标
    int i;
    for (int i = 0; i < G.vex; i++)
    {
        if (v == G.verices[i].data)
        {
            return i;
        }
    }
}
void creatALG(ALG &G)
{//无向带权图
    cin >> G.vex;
    // G.edgenum=G.arc;
    G.edgelist = new edgenode[Maxnum];
    char v1, v2;
    int in;
    for (int i = 0; i < G.vex; i++)
    {
        cin >> G.verices[i].data;
    }
    int m = 0;
    while (cin >> v1 >> v2 >> in)
    {
        int i = locatevex(G, v1);
        int j = locatevex(G, v2);
        G.edgelist[m].vex1 = i;//记录每个边结点的下标
        G.edgelist[m].vex2 = j;
        G.edgelist[m].info = in;
        m++;
    }
    G.edgenum = m;
}
typedef struct MSTEdge
{
    int vex1, vex2; /*  边所依附的图中两个顶点*/
    int weight;     /*  边的权值*/
} MSTEdge;
void sort(ALG &G)
{//对结构按权值从小到大进行排序(冒泡排序)
    for (int i = 1; i <= G.edgenum - 1; i++)
    {
        for (int j = G.edgenum - 1; j > i - 1; j--)
        {
            if (G.edgelist[j].info < G.edgelist[j - 1].info)
            {
                ALG tmp;
                tmp.edgelist = new edgenode[Maxnum];
                tmp.edgelist[0] = G.edgelist[j];//交换
                G.edgelist[j] = G.edgelist[j - 1];
                G.edgelist[j - 1] = tmp.edgelist[0];
            }
        }
    }
}
void Kruskal_MST(ALG &G, int &cnt) /*   用Kruskal算法构造图G的最小生成树*/
{
    MSTEdge TE[Maxnum];//最小生成树的存储结构
    int j, k, v, s1, s2, Vset[Maxnum];//vest辅助数组用于判断是否出现回路
    int w;
    for (j = 0; j < G.vex; j++)
        Vset[j] = j; /*   初始化数组Vset[n]  */
    sort(G);         /*   对表按权值从小到大排序*/
    j = 0;
    k = 0;
    while (k < G.vex - 1 && j < G.edgenum)
    {//遍历n-1个结点,并且小于边数
        s1 = Vset[G.edgelist[j].vex1];
        s2 = Vset[G.edgelist[j].vex2]; /*  若边的两个顶点的连通分量编号不同, 边加入到TE中*/
        if (s1 != s2)
        {//相同则代表出现回路
            TE[k].vex1 = G.edgelist[j].vex1;
            TE[k].vex2 = G.edgelist[j].vex2;
            TE[k].weight = G.edgelist[j].info;
            cnt += G.edgelist[j].info;//记录各边权值和
            k++;//结点数加一
        }
        for (v = 0; v < G.vex; v++)
        {//更新辅助数组(把出现的结点值设成一致)
            if (Vset[v] == s2)
                Vset[v] = s1;
        }
        j++;//边加一
    }
}
int main()
{
    ALG G;
    creatALG(G);
    int cnt = 0;//记录最小生成树权值和
    Kruskal_MST(G, cnt);
    cout << cnt << "\n";
    return 0;
}

 

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值