克鲁斯卡尔算法

article/2025/11/10 18:58:03

什么是克鲁斯卡尔算法

在知道克鲁斯卡尔算法之前我们先来看一下什么是最小生成树。

  • 最小生成树:在一个有n个结点的无向图中选出最少的边,保证所选边权相加之和最小以及该图中依然有n个结点并且n个结点连通。
  • 一共有n个结点,要保证连通,至少需要n-1条边。
  • 最小生成树的权值: w ( t ) = ∑ ( u , v ) ∈ t w ( u , v ) w(t)=\sum\limits_{(u,v)\in t}^{}w(u,v) w(t)=(u,v)tw(u,v)

下面我们用图看一下什么是最小生成树:

在这里插入图片描述
在该图中,我们留下这四条边就可以保证各个结点是连通的了,同时也保证所有边权之和最小,所以这个图的最小生成树权值为: 1 + 2 + 3 + 5 = 11 1+2+3+5=11 1+2+3+5=11
在这里插入图片描述
在了解了什么是最小生成树之后,我们来看克鲁斯卡尔算法是如何求最小生成树的。
思路:

  1. 先按边权从小到达排序。
  2. 从小到大依次看每条边,如果中途发现某一条边的所依附的点已经连通了,就直接跳过,直到n个点连通。

让我们对上面的图稍作修改作为新图模拟一遍克鲁斯卡尔算法:
(1)修改后图(此图为新图)

在这里插入图片描述
(2)
开始克鲁斯卡尔算法来找到第一条边
在这里插入图片描述
(3)
找到第二条边

在这里插入图片描述
(4)
找到第三条边
在这里插入图片描述
(5)
当找到第四条边时,我们发现第四条边两边所依附的点已经是连通的了,根据克鲁斯卡尔算法的思路,我们是要去掉这条边的。为什么要去掉这条边呢? 既然这两个点已经连通了,那我们肯定是可以不选这条边的,不选这条边必然不会让结果变得更差,所以我们直接跳过这条边。
在这里插入图片描述
(6)
找到第五条边,找完五条边可以发现此时此刻所有的点已经连通了,最小生成树已经找到!
最小生成树的权值: 1 + 2 + 3 + 5 = 11 1+2+3+5=11 1+2+3+5=11
在这里插入图片描述

核心代码(C++)

在克鲁斯卡尔算法中,习惯开一个结构体来存每条边和两边的点。

struct Edge{int a,b,w;  //a结点和b结点有一条边权为w的边bool operator<(const Edge &W)const{   //重载小于号,按w排序return w<W.w;}
}edges[N];

判断连通可以用并查集来判断,如果在同一个集合内说明已经连通。

//并查集
int find(int x){if(x!=p[x]) p[x]=find(p[x]);return p[x];
}

题目:

给定一个 n n n 个点 m m m 条边的无向图,图中可能存在重边和自环,边权可能为负数。

求最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible

给定一张边带权的无向图 G = ( V , E ) G=(V,E) G=(V,E),其中 V 表示图中点的集合,E 表示图中边的集合, n = ∣ V ∣ n=|V| n=V m = ∣ E ∣ m=|E| m=E

V V V 中的全部 n n n 个顶点和 E E E n − 1 n−1 n1 条边构成的无向连通子图被称为 G G G 的一棵生成树,其中边的权值之和最小的生成树被称为无向图 G G G 的最小生成树。

输入格式
第一行包含两个整数 n n n m m m

接下来 m 行,每行包含三个整数 u u u, v v v, w w w,表示点 u u u 和点 v v v 之间存在一条权值为 w w w 的边。

输出格式
共一行,若存在最小生成树,则输出一个整数,表示最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible

数据范围
1 ≤ n ≤ 1 0 5 1≤n≤10^5 1n105
1 ≤ m ≤ 2 ∗ 1 0 5 1≤m≤2∗10^5 1m2105
图中涉及边的边权的绝对值均不超过 1000

输入样例:

4 5
1 2 1
1 3 2
1 4 3
2 3 2
3 4 4

输出样例:

6

AC代码(C++)

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;const int N=2e5+10,INF=0x3f3f3f3f;
int p[N];
int n,m;
int res;//按边排序
struct Edge{int a,b,w;bool operator<(const Edge &W)const{return w<W.w;}
}edges[N];//并查集
int find(int x){if(x!=p[x]) p[x]=find(p[x]);return p[x];
}bool kruskal(){sort(edges,edges+m);int cnt=0;  //边数for(int i=1;i<=n;i++) p[i]=i;for(int i=0;i<m;i++){int a=edges[i].a,b=edges[i].b,w=edges[i].w;a=find(a),b=find(b);if(a!=b){  //判断是否在一个集合p[a]=b;cnt++;res+=w;}}return cnt==n-1;
}int main(){int a,b,w;scanf("%d%d",&n,&m);for(int i=0;i<m;i++){scanf("%d%d%d",&a,&b,&w);edges[i]={a,b,w};}int t=kruskal();if(!t) puts("impossible");else printf("%d",res);return 0;
}

http://chatgpt.dhexx.cn/article/yWnHKMBM.shtml

相关文章

Kruskal算法(克鲁斯卡尔算法)

Kruskal算法 Kruskal算法是一种用来查找最小生成树的算法&#xff0c;由Joseph Kruskal在1956年发表。用来解决同样问题的还有Prim算法和Boruvka算法等。三种算法都是贪心算法的应用。 概念解释 Kruskal算法定义&#xff1a;**先构造一个只含 n 个顶点、而边集为空的子图&…

KruskalAlgorithm(克鲁斯卡尔算法)

KruskalAlgorithm介绍 克鲁斯卡尔(Kruskal)算法&#xff0c;是用来求加权连通图的最小生成树的算法。基本思想&#xff1a;按照权值从小到大的顺序选择 n-1 条边&#xff0c;并保证这 n-1 条边不构成回路具体做法&#xff1a;首先构造一个只含 n 个顶点的森林&#xff0c;然后…

数据结构——克鲁斯卡尔(Kruskal)算法

克鲁斯卡尔算法是求连通网的最小生成树的另一种方法。与普里姆算法不同&#xff0c;它的时间复杂度为O&#xff08;eloge&#xff09;&#xff08;e为边数&#xff09;&#xff0c;适合于求边稀疏的网的最小生成树 。克鲁斯卡尔算法从另一途径求网的最小生成树。其基本思想是&a…

克鲁斯卡尔(Kruskal)算法(严蔚敏C语言)

克鲁斯卡尔算法(Kruskal) ​ 克鲁斯卡尔算法是求连通网的最小生成树的另一种方法。与普里姆算法不同&#xff0c;它的时间复杂度为O&#xff08;eloge&#xff09;&#xff08;e为网中的边数&#xff09;&#xff0c;所以&#xff0c;适合于求边稀疏的网的最小生成树 。 ——百…

4.《学会提问》

1.书中的观点 批判性思维会教你很多技能和态度&#xff0c;让你理性地找到对自己有意义的答案并为此感到自豪。批判性思维鼓励你倾听他人&#xff0c;向别人学习&#xff0c;同时掂量别人所说的话&#xff0c;看看它们的分量如何。如此&#xff0c;你将了解到我们必须要依赖他人…

如何提问——提问的艺术

转存失败重新上传取消https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/master/README-zh_CN.md

《提问的艺术》读书笔记

分享读《提问的艺术》的xmind总结&#xff0c;每周听一本书&#xff0c;打卡第一周

(转载) 提问的艺术

虽然这是老话常谈&#xff0c;但是最近的回答问题的过程中&#xff0c;有点感触。你问题问的好&#xff0c;问的准确&#xff0c;回答你的人才有积极性给你答复&#xff0c;这样你又可以更快的解决你的问题。好多人不知道如何提问&#xff0c;所以我打算把这篇老文章转过来置顶…

论程序员提问的艺术

最近工作比较忙&#xff0c;加上空闲时间大部分都是在维护开发【云狗AI】&#xff0c;所以也有一段时间没更新视频了&#xff0c;有不懂的&#xff0c;也可以问一下【云狗AI】以后我也会花更多的时间在维护这个项目中。争取给大家带来更好的体验。 主要是因为最近没发现什么特…

提问的艺术[转]

这是刚看到的 所以转一下 也是警示自己的伸手行为 原文&#xff1a;How To Ask Questions The Smart Way 译文链接&#xff1a;提问的艺术 作者&#xff1a; 艾瑞克.史蒂文.雷蒙德(Eric Steven Raymond) <esrthyrsus.com> 瑞克.莫恩(Rick Moen) <respond-autolinuxmaf…

【提问的艺术】

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…

提问的艺术/怎么高效的提问

唉,可能是因为见过的人多了吧,不管是在现实世界中,还是在网络上,总是需要向别人询问一些东西的, 有的人来问,谦谦有礼,感觉很好,帮助了别人,也没损失什么,有的人来问,就是真心不想搭理他,搭理了他就是 浪费自己的时间,还心理不好受的. 今天不说现实中怎么提问.就说在互联网上.…

《提问的艺术》读后感

前言提问前 他明明能帮到我却不帮我提问前必知必会的一些事关于搜索引擎 提问时 找准对象学会停顿组织你的问题清晰的发问低声下气代替不了做自己的家庭作业删除无意义的要求不要把问题标记为紧急 即使对你而言的确如此礼貌总是有益的对待无礼提问禁区 总结 前言 众所周知&am…

提问的艺术,原文链接

你提的问题没有任何有用的信息&#xff0c;u hava a poop。 提问的艺术 今天在拉屎的时候看到QQ群里有人问问题&#xff0c;那个问题太他妈蠢了&#xff0c;所以我就写了这一片博客&#xff0c;如果再有人问愚蠢的问题我就把这篇博客丢给他。 提问的艺术 原文链接&#xff…

《提问的艺术:如何快速获得答案》(精读版)

《提问的艺术》《How-To-Ask-Questions-The-Smart-Way》 https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way © 2001 Eric Steve Raymond © 2001 D.H.Grand(nOBODY/Ginux) © 2012 Conmajia《提问的艺术&#xff1a;如何快速获得答案》原著Eric…

Serverlet理解

部分转载自&#xff1a;https://blog.csdn.net/javaloveiphone/article/details/8154791 从上图可以看出 Tomcat 的容器分为四个等级&#xff0c;真正管理Servlet 的容器是Context 容器&#xff0c;一个 Context 对应一个 Web 工程。除了将 Servlet 包装成 StandardWrapper 并作…

java serverlet_Serverlet程序

Serverlet是用Java编写的服务器端程序;主要用于交互地浏览和修改数据&#xff0c;生成动态Web内容; 一个serverlet就是一个继承于HttpServlet抽象类的Java类&#xff1b;下面先看一个简单的例子 import javax.servlet.*;importjavax.servlet.http.HttpServlet;importjavax.serv…

serverlet 区别_jsp serverlet 区别

JSP和Servlet的概念对于JSP初学者来说比较不清楚&#xff0c;以下总结一些个人看法&#xff1a; (1).简单的来说Jsp就是含有Java代码的html&#xff0c;而servlet是含有html的Java代码&#xff1b; (2).Jsp最终也是被解释为servlet并编译再执行&#xff0c;Jsp不过是servlet的另…

Java开发之ServLet详解

一、什么是ServLet&#xff1f; serverLet是javaEE中运行于服务器端的&#xff0c;用于接收和响应HTTP协议的请求的程序。 二、ServLet的三种实现方式 1、实现ServLet接口 步骤&#xff1a; &#xff08;1&#xff09;实现ServLet接口 &#xff08;2&#xff09;重写包括s…

Serverlet的生命周期

1.Servlet的生命周期 Servlet没有main()方法&#xff0c;不能独立运行&#xff0c;它的运行完全由Servlet引擎来控制和调度。所谓生命周期 &#xff0c;指的是servlet容器何时创建servlet实例、何时调用其方法进行请求的处理、何时并销毁其实例的 整个过程。其完整的周期包括…