按照惯例,接下来是本篇目录:

$1 什么是最小生成树?

$2 什么是克鲁斯卡尔算法?

$3 克鲁斯卡尔算法的例题

摘要:本片讲的是最小生成树中的玄学算法--克鲁斯卡尔算法,然后就没有然后了。

$1 什么是最小生成树?

•定义:

  先引入一个定理:N个点用N-1条边连接成一个联通块,形成的图形只可能是,没有别的可能;

  根据这个定理,我们定义:在一个有N个点的图中,选出N-1条边出来,连接所有N个点,这N-1条边的边权之和最小的方案;

•最小生成树之prim算法:

   由于本蒟蒻还不会这个算法,所以暂时将这个算法放在这里,讲讲思路,代码实在不会打QAQ

  算法思路:

  1. 从图中选取一个节点作为起始节点(也是树的根节点),标记为已达;初始化所有未达节点到树的距离为到根节点的距离

  2. 从剩余未达节点中选取到树距离最短的节点i,标记为已达;更新未达节点到树的距离(如果节点到节点i的距离小于现距离,则更新);

  3. 重复步骤2直到所有n个节点均为已达。

$2 什么是克鲁斯卡尔算法?

接下来是正题--克鲁斯卡尔算法

•算法思路:

  (1)将所有边的边权从小到大依次排列,并且均标为未选

  (2)选择最小的未选边

  (3)如果该边与前面所选的边无法构成回路,则选中该边,并标为已选;如果该边与前面所选的边构成了回路,则不选该边,并标为已选

  (4)重复(2)(3),直到所有点之间都有边相连;

•举个栗子:

  以下面这个图为例:

  

  将各条边排序可得 3-4-5-6-6-7-8-9-12;

  首先将最小的的边选上,即2--3,如图:

  

  接下来,将第二条边选上,即1--2,如图:

  

  第三条边:

  

  第四条边是6,但是与前三条边构成了回路,不选它;

  第五条边:

  

  第六条边:

  

  最后一条边:

  

•代码实现:

  

 struct point
{
int x;//始边
int y;//终边
int v;//边的权值
};
point a[];
int fat[];
int n,i,j,x,m,tot,k;
int father(int x)//并查集中的查找
{
if(fat[x]!=x) fat[x]=father(fat[x]);
return fat[x];
} void unionn(int x,int y)//并查集中的合并
{
int fa=father(x);
int fb=father(y);
if(fa!=fb) fat[fa]=fb;
} int cmp(const point &a,const point &b)
{
if(a.v<b.v) return ;//对边的权值进行排序
else return ;
} int main()
{
cin>>n;
for(int i=;i<=n;++i)
for(int j=;j<=n;++j)
{
cin>>x;
if(x!=)
{
m++;
a[m].x=i;a[m].y=j;a[m].v=x;
}
}
for(int i=;i<=n;++i) fat[i]=i;
sort(a+,a+m+,cmp);
for(int i=;i<=m;++i)
{
if(father(a[i].x)!=father(a[i].y))
{
unionn(a[i].x,a[i].y);
tot+=a[i].v;
k++;
}//如果不能构成一个联通块,就将现在的这条边加入并查集
if(k==n-) break;//否则将现在的这条边撇开不管
}
cout<<tot;
return ;
}

  神仙们想必都已经看出来了,克鲁斯卡尔算法用到了并查集的思想(不会并查集的神仙戳这儿),还是很好理解的。

$3 克鲁斯卡尔算法的例题

•有且只有的一个例题: 洛谷P1546 最短网络 Agri-Net:

题目背景

农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。当然,他需要你的帮助。

题目描述

约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了用最小的消费,他想铺设最短的光纤去连接所有的农场。

你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。每两个农场间的距离不会超过100000

输入输出格式

输入格式:

第一行: 农场的个数,N(3<=N<=100)。

第二行..结尾: 后来的行包含了一个N*N的矩阵,表示每个农场之间的距离。理论上,他们是N行,每行由N个用空格分隔的数组成,实际上,他们限制在80个字符,因此,某些行会紧接着另一些行。当然,对角线将会是0,因为不会有线路从第i个农场到它本身。

输出格式:

只有一个输出,其中包含连接到每个农场的光纤的最小长度。

输入输出样例

  输入样例#1: 复制

  4
  0 4 9 21
  4 0 8 17
  9 8 0 16
  21 17 16 0
  输出样例#1: 复制

  28
接下来是我懒得讲的代码(和上面一样)
 #include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
struct point
{
int x;
int y;
int v;
};
point a[];
int fat[];
int n,i,j,x,m,tot,k;
int father(int x)
{
if(fat[x]!=x) fat[x]=father(fat[x]);
return fat[x];
} void unionn(int x,int y)
{
int fa=father(x);
int fb=father(y);
if(fa!=fb) fat[fa]=fb;
} int cmp(const point &a,const point &b)
{
if(a.v<b.v) return ;
else return ;
} int main()
{
cin>>n;
for(int i=;i<=n;++i)
for(int j=;j<=n;++j)
{
cin>>x;
if(x!=)
{
m++;
a[m].x=i;a[m].y=j;a[m].v=x;
}
}
for(int i=;i<=n;++i) fat[i]=i;
sort(a+,a+m+,cmp);
for(int i=;i<=m;++i)
{
if(father(a[i].x)!=father(a[i].y))
{
unionn(a[i].x,a[i].y);
tot+=a[i].v;
k++;
}
if(k==n-) break;
}
cout<<tot;
return ;
}

enddd~~

最小生成树--克鲁斯卡尔算法(Kruskal)的更多相关文章

  1. 贪心算法(Greedy Algorithm)之最小生成树 克鲁斯卡尔算法(Kruskal&#39;s algorithm)

    克鲁斯卡尔算法(Kruskal's algorithm)是两个经典的最小生成树算法的较为简单理解的一个.这里面充分体现了贪心算法的精髓.大致的流程能够用一个图来表示.这里的图的选择借用了Wikiped ...

  2. 贪心算法(Greedy Algorithm)最小生成树 克鲁斯卡尔算法(Kruskal&#39;s algorithm)

    克鲁斯卡尔算法(Kruskal's algorithm)它既是古典最低的一个简单的了解生成树算法. 这充分反映了这一点贪心算法的精髓.该方法可以通常的图被表示.图选择这里借用Wikipedia在.非常 ...

  3. 图->连通性->最小生成树(克鲁斯卡尔算法)

    文字描述 上一篇博客介绍了最小生成树(普里姆算法),知道了普里姆算法求最小生成树的时间复杂度为n^2, 就是说复杂度与顶点数无关,而与弧的数量没有关系: 而用克鲁斯卡尔(Kruskal)算法求最小生成 ...

  4. 最小生成树-克鲁斯卡尔算法(kruskal's algorithm)实现

    算法描述 克鲁斯卡尔算法是一种贪心算法,因为它每一步都挑选当前最轻的边而并不知道全局路径的情况. 算法最关键的一个步骤是要判断要加入mst的顶点是否会形成回路,我们可以利用并查集的技术来做. 并查集的 ...

  5. 最小生成树练习1(克鲁斯卡尔算法Kruskal)

    今天刷一下水题练手入门,明天继续. poj1861 Network(最小生成树)新手入门题. 题意:输出连接方案中最长的单根网线长度(必须使这个值是所有方案中最小的),然后输出方案. 题解:本题没有直 ...

  6. 克鲁斯卡尔算法(Kruskal算法)求最小生成树

    题目传送:https://loj.ac/p/10065 1.排序函数sort,任何一种排序算法都行,下面的示例代码中,我采用的是冒泡排序算法 2.寻源函数getRoot,寻找某一个点在并查集中的根,注 ...

  7. 最小生成树之Kruskal(克鲁斯卡尔)算法

    学习最小生成树算法之前我们先来了解下下面这些概念: 树(Tree):如果一个无向连通图中不存在回路,则这种图称为树. 生成树 (Spanning Tree):无向连通图G的一个子图如果是一颗包含G的所 ...

  8. c/c++ 用克鲁斯卡尔(kruskal)算法构造最小生成树

    c/c++ 用克鲁斯卡尔(kruskal)算法构造最小生成树 最小生成树(Minimum Cost Spanning Tree)的概念: 假设要在n个城市之间建立公路,则连通n个城市只需要n-1条线路 ...

  9. 最小生成树之克鲁斯卡尔(Kruskal)算法

    学习最小生成树算法之前我们先来了解下 下面这些概念: 树(Tree):如果一个无向连通图中不存在回路,则这种图称为树. 生成树 (Spanning Tree):无向连通图G的一个子图如果是一颗包含G的 ...

随机推荐

  1. springmvc源码分析——入门看springmvc的加载过程

    本文将分析springmvc是如何在容器启动的时候将各个模块加载完成容器的创建的. 我知道在web.xml文件中我们是这样配置springmvc的: 可以看到,springmvc的核心控制器就是Dis ...

  2. vue 相关

    1.vue v-for 循环一个数组,key值报错,但是数据是正常显示的 报错: v-for使用key,需要在key前加上:key;srcList是个数组,key值绑定不能是数据类型Object的it ...

  3. css浮动学习

    以前网页中的局都是使用浮动来实现的(毕竟ie9也不支持flex-box).而浮动在css中是一个挺难理解的概念,这次再巩固一下,float的具体使用事项. 1.行内元素和块元素的区别? 行内元素(im ...

  4. DAY30、网络编程

    一.网络编程 软件开发 c/s架构 c:客户端 s:服务端 b/s架构 b:浏览器 s:服务端 本质:b/s其实也是c/s 服务端:24小时不间断提供服务,谁来救服务谁 客户端:想什么时候体验服务,就 ...

  5. Forethought Future Cup - Elimination Round

    A:签到. #include<bits/stdc++.h> using namespace std; #define ll long long char getc(){char c=get ...

  6. BZOJ 2733 永无乡

    splay启发式合并 启发式合并其实就是把集合数量小的合并到集合数量大的里去. 怎么合并呢,直接一个一个插入就行了.. 用并查集维护连通性,find(i)可以找到所在splay的编号 这题好像还可以合 ...

  7. 【XSY3345】生成树 并查集

    题目大意 有一个两部各有 \(n\) 个节点的二分图 \(G\),定义 \(G^m\) 为一个 \(m+1\) 层的图,每层有 \(n\) 个节点,相邻两层的诱导子图都和 \(G\) 相同. 给你 \ ...

  8. JS设置Cookie过期时间

    //JS操作cookies方法! //写cookies function setCookie(name,value) { var Days = 30; var exp = new Date(); ex ...

  9. Gradle里面两个 依赖管理插件,可以不用关心 具体jar版本号

    引用:https://spring.io/blog/2015/02/23/better-dependency-management-for-gradle Using the plugin with S ...

  10. vue-微信支付or支付宝支付片段

      <ulclass="way_list"> <li v-if="!isWeixinBrowser" class="group al ...