最小生成树模板&&总结--Prim&&Kruskal

最小生成树——普里姆算法(Prim算法)和克鲁斯卡尔算法(Kruskal算法) 一、普里姆算法 (1)将v0到其他顶点的所有边当作侯选边; (2)重复一下步骤n-1次,使得其他n-1个顶点被并入到生成树中。 ①从侯选边中挑选出权值最小的边输出,并将与该边另一端相接的顶点v并入生成树中; ②考查所有剩余顶点vi,如果(v,vi)的权值比lowcost[vi]小,则用(v,vi)的权值更新lowcost[vi]。 /*邻接矩阵的结构定义*/ typedef struct{ int no; //顶点编号 //char info; //顶点其他信息 }VertexType; type 阅读详情

一.最小生成树:连通N个点的边权值总和最小的树。

二.时间复杂度

Prim算法:时间复杂度O(|V|2+|E|),O(|E|log|V|)

Kruskal算法:时间复杂度O(|E|log|E|)

算法的选择: 从图的稀疏程度考虑(稠密图Prim,稀疏图Kruskal或Prim + Heap)

三.具体算法

  1.Prim算法:(1) 任意选定一点s,设集合S={s}

                       (2) 从不在集合S的点中选出一个点j使得其与S内的某点i的距离最短,则(i,j)就是生成树上的一条边,同时将j点加入S

                       (3) 转到(2)继续进行,直至所有点都己加入S集合

     Prim模板:

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <vector>
#define Twhile() int T;scanf("%d",&T);while(T--)
#define ArrInit(a,b,n) for(int i=0;i<=n;i++)a[i]=b
#define ArrInit2(a,b,n,m) for(int i=0;i<=n;i++)for(int j=0;j<=m;j++)a[i][j]=b
#define fora(i,a,b) for(int i=a;i<b;i++)
#define fors(i,a,b) for(int i=a;i>b;i--)
#define fora2(i,a,b) for(int i=a;i<=b;i++)
#define fors2(i,a,b) for(int i=a;i>=b;i--)
#define PI acos(-1.0)
#define eps 1e-6
#define INF 0x3f3f3f3f

typedef long long LL;
typedef long long LD;
using namespace std;
const int maxn=2000+11;
int ma[maxn][maxn];
int N,M;//点数,边数
int ans;//最小生成树的权值之和
//stack<int>S;  //最小生成树加入的点的顺序
//int lowerPoint[maxn]; // i离S中的lowerPoint[i]最近
int lowerCost[maxn],use[maxn];//lowerCost离S的最小距离,use是否被加入S
void init()
{
    ans=0;
    ArrInit2(ma,INF,N,N);
    ArrInit(use,0,N);
}
void primInit()
{
//    S.push(1);
    use[1]=1;
    lowerCost[1]=0;
//    lowerPoint[1]=1;
    fora2(i,2,N)
    {
//        lowerPoint[i]=1;
        lowerCost[i]=ma[1][i];
    }
}
void prim()
{
    primInit();
    int n=N-1;
    while(n--){
    int k=-1,tem=INF;
    fora2(i,2,N)//找到距离S集合最小的点
    {
        if(use[i])continue;
        if(lowerCost[i]<tem)
        {
            tem=lowerCost[i];
            k=i;
        }
    }
    use[k]=1;
    ans+=tem;
    /*
    lowerCost[k]=0;lowerPoint[i]=i;  //不更新的话,当要求输出最小生成树的边可以直接输出
    S.push(k);
    */
    fora2(i,1,N)
    {
        if(use[i])continue;
        int t=ma[i][k];
        if(t<lowerCost[i])
        {
            lowerCost[i]=t;
            //lowerPoint[i]=k;
        }
    }
    if(tem==INF)return;//图不连通
    }
}

int main()
{

    while(~scanf("%d",&N)&&N)
    {
        scanf("%d",&M);
        init();
        while(M--)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            ma[x][y]=min(ma[x][y],z);
            ma[y][x]=min(ma[y][x],z);
        }
        if(N==1){printf("0\n");continue;}
        prim();
        printf("%d\n",ans);
    }
    return 0;
}

例子:UVALive - 2515 Networking

     UVA - 10369

 

 2.Kruskal算法:(1) 将边按权值从小到大排序后逐个判断,如果当前的边加入以后不会产生环,那么就把当前边作为生成树的一条边

         (2) 最终得到的结果就是最小生成树

 Kruskal模板:

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <vector>
#define Twhile() int T;scanf("%d",&T);while(T--)
#define ArrInit(a,b,n) for(int i=0;i<=n;i++)a[i]=b
#define ArrInit2(a,b,n,m) for(int i=0;i<=n;i++)for(int j=0;j<=m;j++)a[i][j]=b
#define fora(i,a,b) for(int i=a;i<b;i++)
#define fors(i,a,b) for(int i=a;i>b;i--)
#define fora2(i,a,b) for(int i=a;i<=b;i++)
#define fors2(i,a,b) for(int i=a;i>=b;i--)
#define PI acos(-1.0)
#define eps 1e-6
#define INF 0x3f3f3f3f

typedef long long LL;
typedef long long LD;
using namespace std;
const int maxn=5000+11;
int N,M,ans;//点,边,最小生成树
struct edge
{
    int u,v;//点u到v
    int var;//权值
}ma[maxn];
bool cmp(edge a,edge b)
{
    return a.var<b.var;
}
int fa[maxn];
void initKruskal()
{
    ans=0;
    fora2(i,1,N)
    {
        fa[i]=i;
    }
    sort(ma+1,ma+M+1,cmp);

}
/*
Kruskal算法
(1) 将边按权值从小到大排序后逐个判断,如果当前的边加入以后不会产生环,那么就把当前边作为生成树的一条边
(2) 最终得到的结果就是最小生成树
并查集
*/
int findx(int x)
{
    if(x==fa[x])return x;
    return fa[x]=findx(fa[x]);
}
bool unio(int x,int y)
{
    int fx=findx(x),fy=findx(y);
    if(fx==fy)return false;
    fa[fy]=fx;
    return true;
}
void kruskal()
{
    initKruskal();
    int m=0;
    fora2(i,1,M)
    {
        if(unio(ma[i].u,ma[i].v))
        {
            m++;
            ans+=ma[i].var;
            //printf("%d %d  %d\n",ma[i].u,ma[i].v,m);
        }
        if(m==N-1)return;
    }
}

例子:UVALive - 2515 Networking

            I - Kruskal+一点性质 UVALive - 6837There is No Alternative

             J - 最小瓶颈路 UVA - 534 Frogger

【数据结构】克鲁斯卡尔(Kruskal)算法 —PK— 普里姆(Prim)算法 求图的最小生成树的典型算法:克鲁斯卡尔(Kruskal)算法;普里姆(Prim)算法。考虑问题的出发点相同:为使生成树上边的权值之和达到最小,则应使生成树中每一条边的权值尽可能的小。 阅读详情

相关推荐

视觉Transformer实战 | 将卷积引入视觉Transformer(CvT)

CvT 是一种融合卷积神经网络与 Vision Transformer 优势的视觉模型,旨在解决 ViT 缺乏平移不变性和局部性等归纳偏置的问题。CvT 采用分层结构逐级降采样,使用卷积词元嵌入代替传统 patch 切分,引入卷积投影替代线性投影。这些设计使得 CvT 能够去除位置编码,在高分辨率输入下表现更优。本节深入解析 CvT 的核心原理,并提供完整的 PyTorch 代码实现,演示如何在实际数据集上训练和评估 CvT 模型。

盼小辉丶的博客 701

Prim算法和Kruskal算法浅析

Prim算法和Kruskal算法浅析 问题描述 举一个实例,画出采用Prim算法构造最小生成树的过程 举一个实例,画出采用Kruskal算法构造最小生成树的过程 理论解析 Prim: 初始化:向空结果树T=(Vt,Et)中添加图G=(V,E)的任一顶点u0,使Vt={ u0 },Et为空集; 循环(直到Vt=V):从图G中选择满足{(u,v)| u∈Vt,v∈V-Vt}且具有最小权值的边(u,v),并置Vt=Vt∪{v},Et=Et∪{(u,v)}。 Kruskal: 初始化:Vt=V,Et=空集。及使每个

qq_49056623的博客 3527

MathType公式使用技巧汇总——Mathtype怎么在word中编辑公式?论文中公式有哪技巧?有哪些注意事项?论文中的公式怎么写?

如果word中到公式编号(2-1)中间的符号如下图........ .......类似与省略号的,这是手动打的空格,公式和编号的位置都是手动敲空格操作的,这种就只是使用MathType写了公式而已,格式上还是很不方便的。**如果要修改公示,直接双击文档中的公式,就会自动弹出MathType公式编辑窗口,进行修改。如果要修改公示,直接双击文档中的公式,就会自动弹出MathType公式编辑窗口,进行修改。而第二种,是公式里面带的括号符号,他是可以随着公式结构自适应变化的。这时需要将公式插入到一行文字的某处,

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 5万+

最小生成树prim和kruskal算法

最小生成树prim和kruskal算法 一般Kruskal用的比prim多,因为prim可以解决的,kruskal一定可以解决,反过来就不一定了。 prim算法 prim 算法采用的是一种贪心的策略。 每次将离连通部分的最近的点和点对应的边加入的连通部分,连通部分逐渐扩大,最后将整个图连通起来,并且边长之和最小。有点类似与Dijkstra算法。 代码思想和Dijk极其相似,只有dist的定义变了,变成了到集合的最短距离。 #include<cstring> #include<iostr

qq_45766916的博客 1553

最小生成树之普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法

作者:STzen 链接:https://www.jianshu.com/p/683ffde4f3a3 来源:简书 最小生成树 列子引入 如图假设v0到v8表示9个村庄,现在需要在这9个村庄假设通信网络。村庄之间的数字代表村庄之间的直线距离,求用最小成本完成这9个村庄的通信网络建设。 分析 这幅图是一个带权值的图,即网结构。 所谓最小成本,就是n个顶点,用n-1条边把一个连通图连接起来,并且使...

糖长老莫小贝的博客 2万+

图论——最小生成树Prim算法及优化、Kruskal算法,及时间复杂度比较

最小生成树:   一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。简单来说就是有且仅有n个点n-1条边的连通图。   而最小生成树就是最小权重生成树的简称,即所有边的权值之和最小的生成树。   最小生成树问题一般有以下两种求解方式。 一、Prim算法   参考了Feynman的博客    Prim算法通常以邻接矩阵作为...

weixin_30786617的博客 3354

Prim算法和Kruskal算法到底哪个好?

遇到困难时首先想到的不应该是退缩,而是探索!文章粗浅,希望对大家有帮助!【最小生成树Prim算法和Kruskal算法的区别对比Prim算法(java)克鲁斯卡尔算法(Kruskal)详解。

仰望天空,妳我亦是行人. 2162

代码随想录算法训练day63---图论系列7《prim算法&kruskal算法》

今天是算法营的第63天,希望自己能够坚持下来!今天继续图论part!今日任务:● prim算法●kruskal算法prim算法 :1.需要三个数组,一个存放节点和权值vector<vector> grid,一个存放非生成树节点到生成树的最小距离vectorminDist,一个存放节点是否成为生成树节点vectorisInTree。2.循环n-1次,遍历节点,找到是非生成树节点并且距离最小,加入到生成树节点中(isInTree标记为true)3.遍历节点,更新minDist。

qq_38365428的博客 947

51 nod Prim算法&Kruskal算法(贪心之最小生成树Prim、Kruskal)

N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树。输入第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 &lt;= N &lt;= 1000, 1 &lt;= M &lt;= 50000) 第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 &lt;= S, E &lt;= N,1 &lt;= W &lt;= 10000)输出输出最...

放纵不羁爱自由 511

【算法学习笔记】24:Prim算法与Kruskal算法(最小生成树

Prim算法和Dijkstra算法很相似,而且也按照是不是稀疏图分成了两种: 对于稠密图,用朴素版的Prim算法,时间复杂度O(n2)O(n^2)O(n2) 对于稀疏图,用堆优化版的Prim算法,时间复杂度O(mlogn)O(mlogn)O(mlogn) Kruskal算法的时间瓶颈在于它需要对所有边从小到大排序,所以时间复杂度是O(mlogm)O(mlogm)O(mlogm),由于m<n2m < n^2m<n2,所以mlogm<mlog(n2)=2mlognmlogm <

大桔骑士的学习笔记 1825

【算法合集】深搜广搜Prim与Kruskal

广度优先搜索(BFS)又叫广搜,它像一个有远见的人,它是一层一层来实现搜索的,也挺像下楼梯的。 思路: 1.先初始化队列 q; 2.从起点开始访问,并且改变他的状态为已经访问; 3.如果他的队列非空,取出首个元素,将它弹出! 4.如果u == 目标状态,然后对所以与 u 邻近的点进入队列; 5.标记它已经被访问!...............

程序猿追的博客 2万+

最小生成树算法——Prim算法、Kruskal算法

下一条权值最小的边为<V2,V3>或<V3,V4>,因为<V3,V4>与<V4,V6>,<V3,V6>构成环,则只能将<V2,V3>加入边集合中,即。,并将该顶点和相应的边加入T,每次操作后T中的顶点数和边数都增1,重复以上步骤,直至图中所有的顶点都并入T,得到的T就是最小生成树。,若该边依附的顶点落在图中不同的连通分量上,则将边加入图中,否则舍弃该边,选择下一条权值最小的边。下一条权值最小的边为<V3,V6>,将其加入边集合中,即。下一条权值最小的边为<V4,V6>,将其加入边集合中,即。

qq_58098264的博客 3811

实现、比较和改进Prim算法和Kruskal算法

Prim算法和Kruskal算法是两种常用的最小生成树(MST)算法。Prim算法从一个顶点开始,逐步扩展生成树,每次选择与当前生成树相连的最小权重边。Kruskal算法则从所有边中选择最小权重的边,确保不形成环,直到覆盖所有顶点。

星途码客的博客 1770

最小生成树prim算法和kruskal算法

全网最详细的prim和Kruskal算法解析,图文并茂。

2401_86718044的博客 1477

最小生成树问题:Prim(普里姆)算法、Kruskal(克鲁斯卡尔)算法

(2)在已有的生成树节点集合中,选择一个边,且这条边的另一端是未加入树中的节点,且边的权重最小。一个连通的无向加权图 G=(V,E),其中 V 是顶点集合,E 是边集合,每条边都有一个权值(通常为正数,表示距离、成本或权重),寻找 G 中的一棵生成树,使得所有顶点连通且总权值最小。最终生成的最小生成树的边为:(v1,v3)、(v3,v4)、(v4,v6)、(v3,v2)、(v2,v5)最终生成的最小生成树的边为:(v1,v3)、(v3,v4)、(v4,v6)、(v3,v2)、(v2,v5)

qq_57707525的博客 1382

基础图论算法--最小生成树——prim、Kruskal算法

Prim算法更使适应稠密图,时间复杂度为:O(n^2),和Dijkstra算法很相似也肯可以用堆优化来解决稀疏图;但是对于稀疏图,我们更喜欢使用Kruskal(克鲁斯卡尔)算法,时间复杂度为:O(mlogm)Kruskal算法需要判断两个点是否在集合中,以及如何把这两个点连城的一条边加入到集合中,这就需要我们使用。Kruskal算法存边的方法任意,就用最简单的结构体存边即可。特点一:若砍去他的一条边,则会使生成树变成非连通图。,使这条边的两头连通,知道所有的节点都连通。中所有的顶点,并且只含尽可能少的边。

qq_59702185的博客 1047

图的应用——最小生成树Prim 算法和 Kruskal 算法)

参照2025年王道的数据结构考研复习指导书对Prim算法和Kruskal算法构造最小生成树的过程进行了详细的介绍。

kusunoki的博客 3858

Prim算法(普里姆算法)

普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小。 算法描述 1).输入:一个加权连通图,其中顶点集合为V,边集合为E; 2).初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {},为空; 3).重

Lieacui的专栏 6358

Prim、Kruskal、Prim+Heap算法效率实测

评测环境:WindowsXP,FreePascal2.40,Pentium(R) Dual-Core CPU T4300@2.10GHz,2G内存 通过上图可以看出: 1.Prim在稠密图中比Kruskal优,在稀疏图中比Kruskal劣。 2.Prim+Heap在任何时候都有令人满意的的时间复杂度,但是代价是空间消耗极大。【以及代码很复杂>_ 3.时间复杂度

等等... 大雄,有啦! 7008

最小生成树———prim算法和kruskal算法详解

最小生成树prim算法(转载出处) 边赋以权值的图称为网或带权图,带权图的生成树也是带权的,生成树T各边的权值总和称为该树的权。    最小生成树(MST):权值最小的生成树。    生成树和最小生成树的应用:要连通n个城市需要n-1条边线路。可以把边上的权值解释为线路的造价。则最小生成树表示使其造价最小的生成树。    构造网的最小生成树必须解决下面两个问题:     1、尽可能选取...

SYITwin的博客 1万+

Android Studio 4.3 for Windows(android-studio-2020.3.1.25)

Android Studio 4.3(Android Studio Arctic Fox 2020.3.1.25)开发工具版本适用64位的Windows,android-studio-2020.3.1.25-windows.exe,它是Android Studio 4.2.2的下一个版本Android Studio 4.3版本(Android Studio Arctic Fox 2020.3.1.25)。

上一篇: I - Kruskal+一点性质 UVALive - 6837There is No Alternative
下一篇: ACM数学常用知识整理(持续更新ing)
99一零七19
博客等级 码龄9年 12粉丝 67原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值