2017-07-26  10:32:07

writer:pprp

Kruskal算法是根据边的加权值以递增的方式,一次找出加权值最低的边来建最小生成树;并且每次添加的边不能造成生成树有回路,直到找到N-1个边为止;

适用范围:边集比较少的时候,可以考虑用这个方法;

做法:将图形中所有的边的权值,递增排序(快速排序),按从小到大,依次将邻接边加入到生成树中,加入的生成树不能有回路,直到N-1个边;

还用到了并查集;


代码如下:

#include <iostream>

using namespace std;

const int MAXN = ;
const int INF = ;
int n,e;// n是点的数量,e是边的数量
int x[MAXN],y[MAXN],w[MAXN];
int parent[MAXN]; int Find(int x)
{
if(parent[x] == x)
return x;
else
return parent[x] = Find(parent[x]);
} void Merge(int a,int b)
{
int pa = Find(a);
int pb = Find(b);
if(pb < pa)
swap(pb,pa);
if(pa!=pb)
parent[pa] = pb;
} void kruskal()
{
int i,p,ans; //p是已经加入的边数,ans是加入边的边权之和 for(i = ; i<=n ; i++) //initialize
{
parent[i] = i;
} p = ;
ans = ; for(i = ; i <= e; i++)
{
if(Find(x[i])!=Find(y[i]))// 两点没有在同一个集合中,归并两个集合
{
ans += w[i];
Merge(x[i],y[i]);
p++;
if(p == n) //这里不是n-1,因为初始化的时候,p = 1
{
cout << ans << endl;
return;
}
}
}
return;
} void sort(int i, int j)
{
if(i >=j)
return;
int m,n,k;
m = i;
n = j;
k = w[(i+j)>>];
while(m <= n)
{
while(w[m]<k)
m++;
while(w[n]>k)
n--;
if(m <= n)
{
swap(x[m],x[n]);
swap(y[m],y[n]);
swap(w[m],w[n]);
m++;
n--;
}
}
sort(i,n);
sort(m,j);
} int main()
{
int i,j;
cin >> n >> e;
for(i = ; i <= e ; i++)
{
cin >> x[i] >> y[i] >> w[i];
} sort(,e); kruskal(); return ;
}

这个sort函数比较有特点,sort函数根据权值w[MAXN]的大小进行判断,交换的时候将x[MAXN],y[MAXN]都交换了,相当于将 x,y,w对应起来;

图例描述:参考:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html

首先第一步,我们有一张图Graph,有若干点和边

将所有的边的长度排序,用排序的结果作为我们选择边的依据。这里再次体现了贪心算法的思想。资源排序,对局部最优的资源进行选择,排序完成后,我们率先选择了边AD。这样我们的图就变成了右图

在剩下的变中寻找。我们找到了CE。这里边的权重也是5

依次类推我们找到了6,7,7,即DF,AB,BE。

下面继续选择, BC或者EF尽管现在长度为8的边是最小的未选择的边。但是现在他们已经连通了(对于BC可以通过CE,EB来连接,类似的EF可以通过EB,BA,AD,DF来接连)。所以不需要选择他们。类似的BD也已经连通了(这里上图的连通线用红色表示了)。

最后就剩下EG和FG了。当然我们选择了EG。最后成功的图就是右:

Kruskal算法-最小生成树的更多相关文章

  1. POJ-2349(kruskal算法+最小生成树中最大边的长度)

    Arctic POJ-2349 这题是最小生成树的变形题目.题目的意思是已经有s个卫星频道,这几个卫星频道可以构成一部分的网络,而且不用费用,剩下的需要靠d的卫星接收器.题目要求的就是最小生成树中,最 ...

  2. 最小生成树---Prim算法和Kruskal算法

    Prim算法 1.概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (gra ...

  3. 最小生成树的Kruskal算法实现

    最近在复习数据结构,所以想起了之前做的一个最小生成树算法.用Kruskal算法实现的,结合堆排序可以复习回顾数据结构.现在写出来与大家分享. 最小生成树算法思想:书上说的是在一给定的无向图G = (V ...

  4. 最小生成树——kruskal算法

    kruskal和prim都是解决最小生成树问题,都是选取最小边,但kruskal是通过对所有边按从小到大的顺序排过一次序之后,配合并查集实现的.我们取出一条边,判断如果它的始点和终点属于同一棵树,那么 ...

  5. 贪心算法-最小生成树Kruskal算法和Prim算法

    Kruskal算法: 不断地选择未被选中的边中权重最轻且不会形成环的一条. 简单的理解: 不停地循环,每一次都寻找两个顶点,这两个顶点不在同一个真子集里,且边上的权值最小. 把找到的这两个顶点联合起来 ...

  6. Prim算法和Kruskal算法(图论中的最小生成树算法)

    最小生成树在一个图中可以有多个,但是如果一个图中边的权值互不相同的话,那么最小生成树只可能存在一个,用反证法很容易就证明出来了. 当然最小生成树也是一个图中包含所有节点的权值和最低的子图. 在一个图中 ...

  7. 邻接矩阵c源码(构造邻接矩阵,深度优先遍历,广度优先遍历,最小生成树prim,kruskal算法)

    matrix.c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include < ...

  8. 最小生成树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind

    最小支撑树树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind 最小支撑树树 前几节中介绍的算法都是针对无权图的,本节将介绍带权图的最小 ...

  9. 最小生成树Kruskal算法

    Kruskal算法就是把图中的所有边权值排序,然后从最小的边权值开始查找,连接图中的点,当该边的权值较小,但是连接在途中后会形成回路时就舍弃该边,寻找下一边,以此类推,假设有n个点,则只需要查找n-1 ...

随机推荐

  1. cascade(级联)和inverse关系详解

    序言 写这篇文章之前,自己也查了很多的资料来搞清楚这两者的关系和各自所做的事情,但是百度一搜,大多数博文感觉说的云里雾里,可能博主自己清楚是怎么一回事,但是给一个不懂的人或者一知半解的人看的话,别人也 ...

  2. ES6学习之Babel的正确安装姿势

    开始学习ES6,写点东西放上博客^_^ 本文介绍Babel6.x的安装过程~ 首先呢,可以使用Babel在线转换 https://babeljs.io/repl/ 然后进入主题:安装Babel(命令行 ...

  3. 网站行为跟踪 Website Activity Tracking Log Aggregation 日志聚合 In comparison to log-centric systems like Scribe or Flume

    网站行为跟踪 Website Activity Tracking 访客信息处理 Log Aggregation   日志聚合 Apache Kafka http://kafka.apache.org/ ...

  4. django_上传文件

    要求:  写一个文件上传:如果文件名字重复,不要覆盖,并且放到项目根路径的media文件夹下 def upload(request): if request.method == "GET&q ...

  5. 我的Android进阶之旅------>解决Android Studio编译后安装apk报错:The APK file does not exist on disk

    1.错误描述 今天用Android Studio编译应用后安装APK的时候,报错了,错误如下所示: The APK file build\outputs\apk\OYP_2.3.4_I2Base_64 ...

  6. Linux(4)- centos7安装python3、Linux下安装、配置virtualenv、确保开发环境的一致性、虚拟环境之virtualenvwrapper、vim

    一.centos7安装python3 1.下载python3的源码包 下载地址:https://www.python.org/ftp/python/3.6.2/Python-3.6.2.tgz cd ...

  7. Swift学习笔记四:数组和字典

      Swift 提供两种集合类型来存储集合,数组和字典. 数组是一个同类型的序列化列表集合.字典是一个能够使用相似于键的唯一标识符来获取值的非序列化集合.也就是说数组是有序的.字典是无序的. 一. 数 ...

  8. spawn 和 exec 的区别(转载)

    众所周知,Node.js在child_process模块中提供了spawn和exec这两个方法,用来开启子进程执行指定程序.这两个方法虽然目的一样,但是既然Node.js为我们提供了两个方法,那它们之 ...

  9. K NEAREST NEIGHBOR 算法(knn)

    K Nearest Neighbor算法又叫KNN算法,这个算法是机器学习里面一个比较经典的算法, 总体来说KNN算法是相对比较容易理解的算法.其中的K表示最接近自己的K个数据样本.KNN算法和K-M ...

  10. 开博第一篇,学习markdown

    Markdown学习 其实之前自己也一直有记录,不过是Evernote记录,没有分享出来,最近看了一些牛人博客,觉得也应该分享出来.和别人多交流,多学习.所以花了几小时学了一下Markdown语法,现 ...