Kruskal最小生成树【详细解释+动图图解】【sort中的cmp函数】 【例题:洛谷P3366 【模板】最小生成树】

本文主要是介绍Kruskal最小生成树【详细解释+动图图解】【sort中的cmp函数】 【例题:洛谷P3366 【模板】最小生成树】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • Kruskal算法简介
    • Kruskal算法前置知识
      • sort 中的cmp函数
  • 算法思考
    • 样例详细示范与解释
    • kruskal模版code↓
  • 例题:洛谷P3366 【模板】最小生成树code↓
  • 完结撒花QWQ

Kruskal算法简介

K r u s k a l Kruskal Kruskal 是基于贪心算法 M S T MST MST 算法,核心思想为以边为中心查找最小生成树,时间复杂度 O ( m l o g 2 m ) O(mlog_{2}m) O(mlog2m),其中的 m m m 为边数

具体算法可分为两个步骤

1.以边权为优先级来进行排序

2.使用并查集查找连通性,如果不连通,则加边,加答案


Kruskal算法前置知识

1.对于 v e c t o r vector vector 的容器排序算法(使用 s o r t sort sort 即可)

sort(T.begin(),T.end(),cmp);//这是vector的排序方法

解释: T . b e g i n ( ) T.begin() T.begin() v e c t o r vector vector 的起始部分, T . e n d ( ) T.end() T.end() v e c t o r vector vector 的结束部分, T T T v e c t o r vector vector 的容器名

sort 中的cmp函数

c m p cmp cmp s o r t sort sort 重构函数,需要自己定义,这个函数的类型 b o o l bool bool内部变量的类型便是需要排序的容器的类型

cmp模版code如下↓

T name;
bool cmp(T x,T y){return x op y}
sort(name(first),name(last),cmp)

T T T容器类型 n a m e name name容器名字 n a m e ( f i r s t ) name(first) name(first) 代表容器的第一位 n a m e ( l a s t ) name(last) name(last) 表示容器的最后一位


2.使用结构体的构造来赋值

Edge(int a,int b,int c):u(a),v(b),w(c){};

上述构造函数的代码的意思等同于↓:

Edge(int a,int b,int c){u=a,v=b,w=c;}

在结构体里加边的操作也就为:T.push_back(Edge(u,v,w));


3.容器 v e c t o r vector vector 的定义

我们需要用容器来管理结构体

也就是将结构体给定义在容器里

vector<Node> T;//其中T为容器名,Node为结构体名

定义code总结↓:

struct Node{int u,v,w;//定义类型Edge(int a,int b,int c):u(a),v(b),w(c){};//使用构造
};
bool (Node x,Node y){return x.w<y.w}//具体使用vector里的哪一个定义排序的函数
vector<Node> T;//使用容器来管理结构体
sort(T.begin(),T.end(),cmp)//其中T为容器名

算法思考

我们先给出一个题目来进行思考↓:

x x x 市共有 n n n 个岛屿, m m m 种修桥的方案由于 x x x 市的市长是一个黑心市长,所以他想要选择一种方案使得总共修桥的钱最少
每年他可以修一座桥,问:需要几年才能使得所有的岛屿之间都可以互相同行,最少修桥的钱为多少?

我们可以知道:修桥的钱数就是边权,岛屿的名字就是点的编号

第一个问题很好解答,使得所有点之间都可以连通的最少边数 N − 1 N-1 N1 条边

第二个问题我们就需要进行 K r u s k a l Kruskal Kruskal 进行求最小生成树

输入格式为
1 1 1 行,两个整数 n n n , m m m
2 2 2 ~ n + 1 n+1 n+1 行,每行三个整数 u u u , v v v , w w w ,表示所连接的两点及其边权

我们先给出一组样例↓

4 6
1 2 11
2 3 13
3 4 9
4 1 21
1 3 23
4 2 20

样例解释如图示↓
在这里插入图片描述

样例详细示范与解释

因为我们是需要" 花最少的钱,办最多的事 ",所以我们需要先以边的权值为优先级进行排序,结果为↓

3 4 9
1 2 11
2 3 13
4 2 20
4 1 21
1 3 23

那么我们就可以开始进行判断了,每一次重复的过程为:查找两个点是否连通,如果不连通,则加边

int x=find(wei[i].u),y=find(wei[i].v);//查找两个点的祖先if(x!=y){//如果祖先相同,则他们连通,在同一个集合内f[x]=y;//将两条边连在一起ans+=wei[i].w;//将它的权值加在最终答案里cnt++;//已经连接的边数+1}

解释:因为我们最开始已经排过序了,所以如果不连通,那么这条边一定是连接这两个点的最小代价

最后,如果两个点不连通,直接加边和答案,如果边数已经满足最少边数 N − 1 N-1 N1 条,则返回答案

return cnt==n-1?ans:-1;//如果边数是n-1条则返回答案,否则没有答案,无法连接所有边

如何使用并查集查找两个点的连通性,可见我的另一篇博文:并查集【模版】& 路径压缩优化

动图视频如下:

kruskal模版code↓

int kruskal(int n,int m,vector<Edge> &wei){sort(wei.begin(),wei.end(),cmp);int ans=0,cnt=0;for(int i=0;i<m;i++){int x=find(wei[i].u),y=find(wei[i].v);if(x!=y){f[x]=y;ans+=wei[i].w;cnt++;}}return cnt==n-1?ans:-1;
}

例题:洛谷P3366 【模板】最小生成树code↓

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+7;
struct Edge{int u,v,w;Edge(int a,int b,int c):u(a),v(b),w(c){};
};
int f[maxn]={},n,m;
bool cmp(Edge x,Edge y){return x.w<y.w;
}
int find(int x){return f[x]==x?x:f[x]=find(f[x]);} 
vector<Edge> wei;
int kruskal(int n,int m,vector<Edge> &wei){sort(wei.begin(),wei.end(),cmp);int ans=0,cnt=0;for(int i=0;i<m;i++){int x=find(wei[i].u),y=find(wei[i].v);if(x!=y){f[x]=y;ans+=wei[i].w;cnt++;}}return cnt==n-1?ans:-1;
}
int init(){for(int i=1;i<=n;i++) f[i]=i;return 0;
}
int main(){cin>>n>>m;for(int i=1;i<=n;i++) f[i]=i;for(int i=1;i<=m;i++){int u,v,w;cin>>u>>v>>w;wei.push_back(Edge(u,v,w));//因为是无向图,所以需要反过来再加一次边wei.push_back(Edge(v,u,w));}int ans=kruskal(n,2*m,wei);//因为是无向图,所以边数是原边数的两倍if(ans==-1) cout<<"orz";else cout<<ans;return 0;
}

这么一点代码当然是可以 A C AC AC

在这里插入图片描述

完结撒花QWQ

这篇关于Kruskal最小生成树【详细解释+动图图解】【sort中的cmp函数】 【例题:洛谷P3366 【模板】最小生成树】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/844723

相关文章

最新版IDEA配置 Tomcat的详细过程

《最新版IDEA配置Tomcat的详细过程》本文介绍如何在IDEA中配置Tomcat服务器,并创建Web项目,首先检查Tomcat是否安装完成,然后在IDEA中创建Web项目并添加Web结构,接着,... 目录配置tomcat第一步,先给项目添加Web结构查看端口号配置tomcat    先检查自己的to

使用Nginx来共享文件的详细教程

《使用Nginx来共享文件的详细教程》有时我们想共享电脑上的某些文件,一个比较方便的做法是,开一个HTTP服务,指向文件所在的目录,这次我们用nginx来实现这个需求,本文将通过代码示例一步步教你使用... 在本教程中,我们将向您展示如何使用开源 Web 服务器 Nginx 设置文件共享服务器步骤 0 —

SpringBoot集成SOL链的详细过程

《SpringBoot集成SOL链的详细过程》Solanaj是一个用于与Solana区块链交互的Java库,它为Java开发者提供了一套功能丰富的API,使得在Java环境中可以轻松构建与Solana... 目录一、什么是solanaj?二、Pom依赖三、主要类3.1 RpcClient3.2 Public

手把手教你idea中创建一个javaweb(webapp)项目详细图文教程

《手把手教你idea中创建一个javaweb(webapp)项目详细图文教程》:本文主要介绍如何使用IntelliJIDEA创建一个Maven项目,并配置Tomcat服务器进行运行,过程包括创建... 1.启动idea2.创建项目模板点击项目-新建项目-选择maven,显示如下页面输入项目名称,选择

Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)

《Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)》:本文主要介绍Python基于火山引擎豆包大模型搭建QQ机器人详细的相关资料,包括开通模型、配置APIKEY鉴权和SD... 目录豆包大模型概述开通模型付费安装 SDK 环境配置 API KEY 鉴权Ark 模型接口Prompt

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

Spring Boot 中整合 MyBatis-Plus详细步骤(最新推荐)

《SpringBoot中整合MyBatis-Plus详细步骤(最新推荐)》本文详细介绍了如何在SpringBoot项目中整合MyBatis-Plus,包括整合步骤、基本CRUD操作、分页查询、批... 目录一、整合步骤1. 创建 Spring Boot 项目2. 配置项目依赖3. 配置数据源4. 创建实体类

详解Java中如何使用JFreeChart生成甘特图

《详解Java中如何使用JFreeChart生成甘特图》甘特图是一种流行的项目管理工具,用于显示项目的进度和任务分配,在Java开发中,JFreeChart是一个强大的开源图表库,能够生成各种类型的图... 目录引言一、JFreeChart简介二、准备工作三、创建甘特图1. 定义数据集2. 创建甘特图3.

python与QT联合的详细步骤记录

《python与QT联合的详细步骤记录》:本文主要介绍python与QT联合的详细步骤,文章还展示了如何在Python中调用QT的.ui文件来实现GUI界面,并介绍了多窗口的应用,文中通过代码介绍... 目录一、文章简介二、安装pyqt5三、GUI页面设计四、python的使用python文件创建pytho

SpringBoot整合InfluxDB的详细过程

《SpringBoot整合InfluxDB的详细过程》InfluxDB是一个开源的时间序列数据库,由Go语言编写,适用于存储和查询按时间顺序产生的数据,它具有高效的数据存储和查询机制,支持高并发写入和... 目录一、简单介绍InfluxDB是什么?1、主要特点2、应用场景二、使用步骤1、集成原生的Influ