• 原因

    回顾一下旧知识

  • 概况

    在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即),而 w(u, v) 代表此边的权重,若存在 T 为 E 的子集(即)且为无循环图,使得的 w(T) 最小,则此 T 为 G 的最小生成树。

    \(\omega(t)=\sum\limits_{(u,v)\in t}{\omega (u,v)}\)

    最小生成树其实是最小权重生成树的简称

  • 思想

    最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出。

一、kruskal(克鲁斯卡尔)算法

1. 基本思想

基本思想是:假设连通网G = (V,E),令最小生成树的初始状态为只有 n 个顶点而无边的非连通图 T =( V , {} ),
图中每个顶点自成一个连通分量。在E中选择代价最小的边,若该边的顶点分别在T中不同的连通分量上,则将此边加入到T中
否则,舍去此边而选择下一条代价最小的边。依此类推,直至T中所有顶点构成一个连通分量为止

2. 时间复杂度

克鲁斯卡尔的时间复杂度主要由排序方法决定,而克鲁斯卡尔的排序方法只与网中边的条数有关,而与网中顶点的个数无关,
当使用时间复杂度为O(elog2e)的排序方法时,克鲁斯卡尔的时间复杂度即为O(log2e),
因此当网的顶点个数较多、而边的条数较少时,使用克鲁斯卡尔算法构造最小生成树效果较好

ps:记得配和并查集使用

二、prim(普里姆)算法

1. 算法介绍

1).输入:一个加权连通图,其中顶点集合为V,边集合为E;
2).初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {},为空;
3).重复下列操作,直到Vnew = V:
a.在集合E中选取权值最小的边<u, v>,其中u为集合Vnew中的元素,而v不在Vnew集合当中,
并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
b.将v加入集合Vnew中,将<u, v>边加入集合Enew中;
4).输出:使用集合Vnew和Enew来描述所得到的最小生成树。

2. 时间复杂度

最小边、权的数据结构 时间复杂度(总计)
邻接矩阵、搜索 O(V^2)
二叉堆、邻接表 O((V + E) log(V)) = O(E log(V))
斐波那契堆、邻接表 O(E + V log(V))
通过邻接矩阵图表示的简易实现中,找到所有最小权边共需O(V)的运行时间。
使用简单的二叉堆与邻接表来表示的话,普里姆算法的运行时间则可缩减为O(ElogV),其中E为连通图的边数,V为顶点数。
如果使用较为复杂的斐波那契堆,则可将运行时间进一步缩短为O(E+VlogV),
这在连通图足够密集时(当E满足Ω(VlogV)条件时),可较显著地提高运行速度。

(@百度百科

  • 题目

P3366 【模板】最小生成树

模板,致敬,我用的kruskal

#include <bits/stdc++.h>
using namespace std;
struct node{
int x,y,len;
}a[200005]; int f[100005];
int cmp(node num1,node num2){
return num1.len<num2.len;
}
int find(int x){
if (x!=f[x]) f[x]=find(f[x]);
return f[x];
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++){
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].len);
}
long long ans=0;
sort(a+1,a+1+m,cmp);
for (int i=1;i<=n;i++) f[i]=i;
for (int i=1;i<=m;i++){
int x=find(a[i].x),y=find(a[i].y);
if (x!=y){
ans+=a[i].len;
f[x]=y;
}
}
printf("%d",ans);
}

P1991 无线通讯网

** 其中主要就是kruskal,注意排序顺序和找第几大的边 **

#include <bits/stdc++.h>
using namespace std;
int n,m;
int x[1005],y[1005];
int f[1005];
struct node{
int l,r;
double len;
}a[250005];
int h=0;
double ans;
bool cmp(node num1,node num2){
return num1.len<num2.len;
}
int find (int x){
if (x!=f[x]) f[x]=find(f[x]);
return f[x];
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++){
scanf("%d%d",&x[i],&y[i]);
}
for (int i=1;i<=m;i++){
for (int j=i+1;j<=m;j++){
h++;
a[h].l=i;
a[h].r=j;
a[h].len=sqrt(pow(x[i]-x[j],2)+pow(y[i]-y[j],2));
}
}
sort(a+1,a+1+h,cmp);
for (int i=1;i<=m;i++){
f[i]=i;
}
int tot=0;
for (int i=1;i<=h;i++){
int x=find(a[i].l),y=find(a[i].r);
if (x!=y){
++tot;
ans=a[i].len;
f[x]=y;
}
if (tot==m-n){
printf("%.2lf",ans);
break;
}
}
return 0;
}

最小生成树(MST)详解+题目的更多相关文章

  1. 状压DP入门详解+题目推荐

    在动态规划的题型中,一般叫什么DP就是怎么DP,状压DP也不例外 所谓状态压缩,一般是通过用01串表示状态,充分利用二进制数的特性,简化计算难度.举个例子,在棋盘上摆放棋子的题目中,我们可以用1表示当 ...

  2. 树形DP入门详解+题目推荐

    树形DP.这是个什么东西?为什么叫这个名字?跟其他DP有什么区别? 相信很多初学者在刚刚接触一种新思想的时候都会有这种问题. 没错,树形DP准确的说是一种DP的思想,将DP建立在树状结构的基础上. 既 ...

  3. 最小生成树算法详解(prim+kruskal)

    最小生成树概念: 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边. 最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里 ...

  4. 数位DP入门详解+题目推荐

    \(update:2019-9-6\) 博客里某些东西没有解释清楚,完善了对应的解释 在开始之前,我们先来看一道题--题目链接 题目要求,相邻两位的差大于等于2,那么我们先来构造一个试一试. 比如说\ ...

  5. 状压DP详解+题目

    介绍 状压dp其实就是将状态压缩成2进制来保存 其特征就是看起来有点像搜索,每个格子的状态只有1或0 ,是另一类非常典型的动态规划 举个例子:有一个大小为n*n的农田,我们可以在任意处种田,现在来描述 ...

  6. 树形DP详解+题目

    关于树形dp 我觉得他和线性dp差不多 总结 最近写了好多树形dp+树形结构的题目,这些题目变化多样能与多种算法结合,但还是有好多规律可以找的. 先说总的规律吧! 一般来说树形dp在设状态转移方程时都 ...

  7. DP+单调队列详解+题目

    介绍: 单调队列优化的原理   先回顾单调队列的概念,它有以下特征:   (1)单调队列的实现.用双端队列实现,队头和队尾都能插入和弹出.手写双端队列很简单.   (2)单调队列的单调性.队列内的元素 ...

  8. Trie树(字典树,单词查找树)详解+题目

    什么是字典树? 叫前缀树更容易理解 字典树的样子 Trie又被称为前缀树.字典树,所以当然是一棵树.上面这棵Trie树包含的字符串集合是{in, inn, int, tea, ten, to}.每个节 ...

  9. RHCE脚本题目详解

    目录 RHCE脚本题目详解 题目一 shell脚本之if语句实现: shell脚本之case语句实现: 题目二 实现 测试 解析 写在后面 RHCE脚本题目详解 题目一 在system1上创建一个名为 ...

随机推荐

  1. JDBC:(java database Connection) java数据库连接。

    JDBC 指 Java 数据库连接,是一种标准Java应用编程接口( JAVA API),用来连接 Java 编程语言和广泛的数据库. JDBC连接步骤: 1.先导入jar包,把jar放入到工程下并 ...

  2. 微信小程序的支付流程

    一.前言 微信小程序为电商类小程序,提供了非常完善.优秀.安全的支付功能 在小程序内可调用微信的API完成支付功能,方便.快捷 场景如下图所示: 用户通过分享或扫描二维码进入商户小程序,用户选择购买, ...

  3. Scrum Meeting 0602

    零.说明 日期:2021-6-2 任务:简要汇报两日内已完成任务,计划后两日完成任务 一.进度情况 组员 负责 两日内已完成的任务 后两日计划完成的任务 困难 qsy PM&前端 完成后端管理 ...

  4. BUAA2020软工作业(五)——软件案例分析

    项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 软件案例分析作业 我在这个课程的目标是 进一步提高自己的编码能力,工程能力 这个作业在哪个具体方面 ...

  5. csp-s 2021

    T1 廊桥分配 当一架飞机抵达机场时,可以停靠在航站楼旁的廊桥,也可以停靠在位于机场边缘的远机位. 乘客一般更期待停靠在廊桥,因为这样省去了坐摆渡车前往航站楼的周折. 然而,因为廊桥的数量有限,所以这 ...

  6. 2021.7.29考试总结[NOIP模拟27]

    T1 牛半仙的妹子图 做法挺多的,可以最小生成树或者最短路,复杂度O(cq),c是颜色数. 我考场上想到了原来做过的一道题影子,就用了并查集,把边权排序后一个个插入,记录权值的前缀和,复杂度mlogm ...

  7. Less-5闯关失败

    进行第五关的通关还是用之前的方式进行测试以及判断是什么类型的注入.通过判断我们不难发现是字符型注入.但是出了问题,我们会发现按照原来的步骤进行注入都会返回"You are in " ...

  8. 【做题记录】 [HEOI2013]SAO

    P4099 [HEOI2013]SAO 类型:树形 \(\text{DP}\) 这里主要补充一下 \(O(n^3)\) 的 \(\text{DP}\) 优化的过程,基础转移方程推导可以参考其他巨佬的博 ...

  9. Allure快速入门

    1.关于Allure     Allure框架是一个灵活轻量级多语言测试报告工具,它不仅可以以WEB的方式展示简介的测试结果,而且允许参与开发过程的每个人从日常执行的测试中最大限度的提取有用信息.   ...

  10. 有向路径检查 牛客网 程序员面试金典 C++ Python

    有向路径检查 牛客网 程序员面试金典 C++ Python 题目描述 对于一个有向图,请实现一个算法,找出两点之间是否存在一条路径. 给定图中的两个结点的指针DirectedGraphNode* a, ...