最小生成树-贪心算法

本文介绍了最小生成树的概念,包括子图、生成子图、生成树和最先生成树的定义。接着详细阐述了Prim算法和Kruskal算法的原理,Prim算法采用避圈法,通过优先队列优化选择最小边;Kruskal算法按边的权值排序,避免形成环。同时,文章提到了数据结构如临界矩阵、集合和优先队列在算法中的应用,并分析了算法的时间复杂度优化策略。
摘要由CSDN通过智能技术生成

概念引入:

(1)子图:从原图中选中一些定点和边组成的图,称为原图的子图。
(2)生成子图:选中一些边和所有定点组成的图,称为原图的生成子图。
(3)生成树:如果生成子图恰好是一棵树,则成为生成树。
(4)最先生成树:权值之和最小的生成树,则称为最小生成树。
所以最小生成树满足:1.权值最小,2.含有图中每一个结点。
最小生成树算法和前面学到的dijkstr求最短路径的算法及其相似,==
最短路径算法==-从原点出发-找到一个距离当前最近的结点(则该节点就是原点到该结点的最短距离)- 我们用这条边去跟新和其他结点的最短距离,下次再从剩下的未访问的结点中去选最小值,依次推倒下去每次找到的最小结点都是离原点最短距离。
*最小生成树算法-prim *(采用的是避圈法)-先找到离原点最近距离的结点i,再去找该结点到其他结点的距离比如将这些边值存入dist[]数组中,则这个数组中存储的是集合S到V-S集合的结点当然一维数组里面只能存储一个值,那么这个值就是具有最小值的结点,每次过滤dis[]数组中的值的时候我们需要选取的是最小的边值。
图解:从原点出发假设有三条边
图解:
这三条边分别是3->1, 3->4,3->5。
选择权值最小的一条边:
在这里插入图片描述
用红色箭头标记为以确定的边值。这样V集合里面有集合有V={3,5},用阴影标记出来。假设结点的全集为T则剩余结点为:T-V
则V与T-V直接的连线如下:

在这里插入图片描述

可以看到这之间有很多的线而,比如以4为结点的边有3->4,5->4而我们只会选择其中权值较小的一条,在和1,6进行比较。

在这里插入图片描述
找到权值最小的一条为5->6.
依次类推便可以得到所有的边:
在这里插入图片描述
数据结构:
T[][]临界矩阵存储图中的信息,S[]表示以选中的结点集合,lowcost[i]表是到i结点的权值最小的边,cost[i]表示i结点的前驱结点。
prim()函数,1.完成lowcost初始化,2.挑选出离集合T最近的定点x,3.x定点到其他定点的最小值更新lowcost[]。

代码如下:

#include <iostream>
#include <algorithm>
using namespace std;
#define INF 10000
const int maxn= 1000+5;
int T[maxn][maxn];//用于储存结点信息
bool s[maxn];//结点集合
int lowcost[maxn],costest[maxn];//lowcost表示到该结点的最短的边的权值,costest保存的是每个结点的前驱结点。
void  Prim(int u0,int n)//u0:原点 n:结点个数
{
   
    s[u0]=true;//原点标记为0
    for (int i = 1; i <=n ; ++i)
    {
   
        if(i!=u0)
        {
   
            lowcost[i]=T[u0][i];
            s[i]= false;
            costest[i]=u0;
        }
        else
            lowcost[i]=0;
    }//完成初始化
//初始化要做的事情有:先将该结点到其他结点距离初始化给lowcost数组,将所有的结点的前驱标记为u0.
    for (int i = 1; i <=n ; ++i) {
   
        int temp = INF;
        int t = u0;

        for (int i1= 1; i1 <= n; i1++) {
   
            if (!s[i1] && temp > lowcost[i1]) {
   
                temp = lowcost[i1];
                t = i1;
            }
        }//挑选集合S中最小的边的令一个结点

        if (t == u0)
            break;
        s[t] = true;
        for(int j=1;j<=n;j++)
        {
   
            if(!s[j]&&T[t][j]<lowcost[j])//该处便是与最短路径的差别之处
            {
   
                lowcost[j]=T[t][j];//更新出该结点到其他结点的最小距离
                costest[j
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值