为防止网页加载过慢,故分两章。上接https://www.cnblogs.com/Uninstalllingyi/p/10479470.html

Kruskal算法——将森林合并成树

玩过瘟疫公司吗…?这一小片感染…那一小片感染…最后全部感染。诶嘿,游戏胜利。

时间复杂度

O(E*logE),E代表边数。适用于根据图生成最小生成树。

算法思想

首先要掌握两个知识点。首先是边集,然后是并查集。

把无向图中互相连通的一些点称为处于一个连通块中。(如果理解不了…其实可以理解为…相互连通的点是一个版块…或者说染成同一颜色之类的…)

图中有三个连通块。1,2处于同一个连通块中,4,5,6也处于同一个连通块中,孤立点3也称为一个连通块。然后我们利用并查集的思路,把每一个连通块看做一个集合。Kruskal首先要把所有的边按从小到大顺序排序(一般用sort,但是听闻有些变态题需要你用点更快的排序算法。)按顺序枚举边。如果两个边连接着不同的集合,那么就把他并为一个集合。如果属于同一个集合,那就跳过。所以一定是选取了n-1条边(n个点)

那么又到了最痛苦手工模拟环节。

这图里,五个点。都是单独的集合好吧。开始的时候生成树里还没有边。MST就归零。

5个集合{{1},{2},{3},{4},{5}}

然后这个算法每次都选择最小的边。而且这条边的两个顶点都分属于不同的集合。然后把这个边加入最小生成树,并且合并集合。那显而易见,第一次我们选<1,2>这个边。

(这个图是在用实线表示)

于是得到4个集合:{{1,2},{3},{4},{5}},生成树中有1条边{<1,2>},MST+=2=2;

第二次我们选<4,5>

于是得到3个集合:{{1,2},{3},{4,5}},生成树中有2条边:{<1,2>,<4,5>},MST+=3=5;

第三次选<3,5>

于是得到2个集合:{{1,2},{3,4,5}},生成树中有3条边:{<1,2>,<4,5>,<3,5>},MST+=6=11;

第四次选…你以为我会选<3,4>吗?才!不!会!因为这个边连接的3,4都属于同一个集合,所以我们这次选<2,5>

于是得到1个集合:{{1,2,3,4,5}},生成树中有4条边:{<1,2>,<4,5>,<3,5>,<2,5>},MST+=8=19;

经过累死累活的手算,我们发觉选边的条件是这样的:

⑴这条边的两个顶点必须分属于不同的集合
⑵在满足⑴的情况下,这条边的权值最小
⑶一张n个点的图,总共选择n-1次边

然后仔细一想…woc还是贪心的思路。

算法描述

  1. 【算法描述】
  2. ⑴定义边集数组:
  3. struct edge{
  4. int x,y,v;
  5. bool operator<(const edge &eg)const{return v<eg.v;}
  6. }edges[*];
  7. ⑵编写find函数
  8. int find(int x){
  9. if(up[x]!=x) up[x]=find(up[x]);
  10. return up[x];
  11. }
  12. ⑶编写join函数
  13. bool join(int x,int y){
  14. if(find(x)!=find(y)){
  15. up[find(x)]=find(y);
  16. return true;
  17. }
  18. return false;
  19. }
  20. ⑷初始化
  21. idx=;MST=;
  22. for(int i=;i<=n;i++) up[i]=i;
  23. ⑸排序std::sort(edges+,edges+idx+);
  24. ⑹算法核心
  25. for(int i=;i<=idx;i++)
  26. if(join(edges[i].x,edges[i].y)) MST+=edges[i].v;

然后就是洛谷模板题。

https://www.luogu.org/problemnew/show/P3366

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstdio>
  4. //Kruskal
  5. using namespace std;
  6.  
  7. struct edge{
  8. int x,y,v;
  9. }edges[];
  10. bool compare(const edge &eg1,const edge &eg2){
  11. return eg1.v<eg2.v;
  12. }
  13. int n,m,a,b,c,up[],idx,MST;
  14. int find(int x){
  15. if(up[x]!=x){
  16. up[x]=find(up[x]);
  17. }
  18. return up[x];
  19. }
  20. bool join(int x,int y){
  21. if(find(x)!=find(y)){
  22. up[find(x)]=find(y);
  23. return true;
  24. }
  25. return false;
  26. }
  27. int main(){
  28. scanf("%d%d",&n,&m);
  29. for(int i=;i<=m;i++){
  30. scanf("%d%d%d",&a,&b,&c);
  31. edges[++idx].x=a;
  32. edges[idx].y=b;
  33. edges[idx].v=c;
  34. }
  35. sort(edges+,edges+idx+,compare);
  36. for(int i=;i<=n;i++){
  37. up[i]=i;
  38. }
  39. for(int i=;i<=idx;i++){
  40. if(join(edges[i].x,edges[i].y)){
  41. MST+=edges[i].v;
  42. }
  43. }
  44. printf("%d\n",MST);
  45. }

最小生成树(II)与Kruskal算法的更多相关文章

  1. 最小生成树之Prim Kruskal算法(转)

    最小生成树 首先,生成树是建立在无向图中的,对于有向图,则没有生成树的概念,所以接下来讨论的图均默认为无向图.对于一个有n个点的图,最少需要n-1条边使得这n个点联通,由这n-1条边组成的子图则称为原 ...

  2. 洛谷P3366【模板】最小生成树-克鲁斯卡尔Kruskal算法详解附赠习题

    链接 题目描述 如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz 输入输出格式 输入格式: 第一行包含两个整数N.M,表示该图共有N个结点和M条无向边.(N<=5000,M&l ...

  3. 图解最小生成树 - 克鲁斯卡尔(Kruskal)算法

    我们在前面讲过的<克里姆算法>是以某个顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树的.同样的思路,我们也可以直接就以边为目标去构建,因为权值为边上,直接找最小权值的边来构建生成树 ...

  4. HDU1875——畅通工程再续(最小生成树:Kruskal算法)

    畅通工程再续 Description相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现.现在政府决定大力发展百岛湖,发展首先要解决的问题当 ...

  5. 无向带权图的最小生成树算法——Prim及Kruskal算法思路

    边赋以权值的图称为网或带权图,带权图的生成树也是带权的,生成树T各边的权值总和称为该树的权. 最小生成树(MST):权值最小的生成树. 生成树和最小生成树的应用:要连通n个城市需要n-1条边线路.可以 ...

  6. 数据结构之最小生成树Kruskal算法

    1. 克鲁斯卡算法介绍 克鲁斯卡尔(Kruskal)算法,是用来求加权连通图的最小生成树的算法. 基本思想:按照权值从小到大的顺序选择n-1条边,并保证这n-1条边不构成回路. 具体做法:首先构造一个 ...

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

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

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

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

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

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

随机推荐

  1. mysql的InnoDB 数据库引擎TableSpace Exists 问题

    Mysql数据库报错: ERROR 1813 (HY000): Tablespace '`coll`.`t1`' exists. 原因:在使用InnoDB引擎的数据库中,所有已经存在的表都使在使用In ...

  2. 定位权限授权 - iOS

    关于介入地图相关功能后会遇到类似定位的子功能,由此引来了此定位权限授权相关. 首先,需要导入 CoreLocation 的框架并创建管理对象从而实现后续的相关操作; #import <CoreL ...

  3. UIPanGestureRecognizer 拖动TableView改变其高度

    需求:项目中要求tableView的高度随着手拖动的位置而改变如下图: 关键代码如下: - (void)viewDidLoad{ panGestureRecognizer = [[UIPanGestu ...

  4. Windows 安装 MongoDB 并开启认证

    下载 可以自行上官网找需要的版本,Windows系统各个64位版本下载地址: http://dl.mongodb.org/dl/win32/x86_64 安装 正常的软件安装流程,这里就不细讲了. 配 ...

  5. visual studio进程或线程自上一个步骤以来已更改

    1.自己的解决方案:visual studio在多进程执行,在配置页面(webconfig)里把UseCounterThread参数设置为0 2.公司其他人解决方案,自己试了,多进程执行的时候没起作用 ...

  6. linux操作系统的目录以及用户权权限的管理

    linux操作系统的目录以及对目录的操作 一: linux操作系统的目录结构   bin #可执行程序的安装目录 , 命令 boot #系统启动引导目录 dev #设备目录 etc #软件配置文件目录 ...

  7. java的值传递机制

    一.练习:编写Java程序,将二维数组中的行列互调显示出来. 代码1为自己编写: package com.xxgpra.CH6; public class Hangliehudiao_pra4 { p ...

  8. rails中文本匹配相似度gem包对比

    测试数据 ["美科学家发现人体新器官","科学家发现新器官"],["曝高云翔悉尼被捕","高云翔涉性侵被捕"],[&qu ...

  9. idea自动生成testNG.xml

    下载插件  Create TestNG Xml  安装插件 重启后就可以生成testNG.xml,打开xml,ctrl + ALT + L,格式化一下

  10. 为什么我要放弃javaScript数据结构与算法(第四章)—— 队列

    有两种结构类似于数组,但在添加和删除元素时更加可控,它们就是栈和队列. 第四章 队列 队列数据结构 队列是遵循FIFO(First In First Out,先进先出,也称为先来先服务)原则的一组有序 ...