- Kruskal 算法 -

Kruskal 算法:

Kruskal 算法总是维护无向图的最小生成森林。最初,可认为生成森林由零条边构成,每个节点各自构成一棵仅包含一个点的树。在任意时刻,Kruskal 算法从剩余的边中选出一条权值最小的,并且这条边的两个端点属于生成森林中两棵不同的树(不连通),把该边加入生成森林。图中节点的连通情况可以用并查集维护。

复杂度:

时间复杂度:O(nlogn)

算法过程:

1、建立并查集,每个点各自构成一个集合;
2、把所有边按照权值从小到大排序,依次扫描每条边(x,y,z);
3、若 x,y 属于同一集合(连通),则忽略这条边,继续扫描下一条;
4、否则,合并 x,y 所在的集合,并把 z 累加到答案中;
5、所有边扫描完成后,第4步中处理过的边就构成最小生成树。

int par[N];
struct node{int from;//边的起点int w;//边的权值int to;//边的终点
}edge[N*N];bool cmp(node x, node y) {return x.w<y.w;
}void init(int n) {//并查集for(int i=1; i<=n; i++) {par[i]=i;//父亲}
}int find(int a) {if(par[a]==a) return a;else return par[a]=find(par[a]);
}void kruskal(int cnt, int n) {//cnt表示待扫描的边的数目,n表示所有节点的数目sort(edge, edge+cnt, cmp);int ans=0, num=0;for(int i=0; i<cnt; i++) {if(num==n-1) break;//已得到最小生成树跳出循环int a=find(edge[i].from), b=find(edge[i].to);if(a!=b) {par[b]=a;//合并a,b集合ans+=edge[i].w;num++;}}printf("%d\n", ans);return ;
}

例题:

- HDU 1102 -

Constructing Roads

Time Limit: 2000/1000 MS (Java/Others) | Memory Limit: 65536/32768 K (Java/Others)

题意:

给定一个整数 n ,表示村庄数(从1~n编号),接下来 n 行,每行 n 个整数,第 i 行第 j 列的数表示村庄 i 和 村庄 j 之间的距离,然后给定一个整数 q ,接下来 q 行每行有两个数a,b,表示村庄 a、b 之间的路已连通,最后求使得所有村庄互相连通需要修的最短的路。

数据范围:

N (3 <= N <= 100),村庄之间的距离在 [ 1, 1000 ] 范围内,Q (0 <= Q <= N * (N + 1) / 2), (1 <= a < b <= N)

解题思路:

Prime 算法 or Kruskal 算法 以下选择用 Kruskal 算法实现
用 Prime 算法实现的代码链接–>- Prime 算法 -

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
using namespace std;
#define INF 0x3f3f3ftypedef long long ll;
const int N=105;
int par[N], rankk[N];struct node{int from;//边的起点int w;//边的权值int to;//边的终点
}edge[N*N];bool cmp(node x, node y) {return x.w<y.w;
}void init(int n) {//并查集for(int i=1; i<=n; i++) {par[i]=i;//父亲rankk[i]=0;//树的高度}
}//这里合并a,b集合时采用了把更低的树合并到更高的树的方法,虽然可以缩短查找节点的根的时间,但是rankk数组会占用较大内存,如果不会超时的话,其实可以不用那么麻烦,直接令par[b]=a就可以了
void unite(int a, int b) {//并查集if(rankk[a]<rankk[b])par[a]=b;else {par[b]=a;if(rankk[a]==rankk[b])rankk[a]++;}return ;
}int find(int a) {if(par[a]==a) return a;else return par[a]=find(par[a]);//这一步很重要,把节点直接连到根节点上,能大大缩短查找根节点的时间
}void kruskal(int cnt, int n) {//cnt表示待扫描的边的数目,n表示所有节点的数目sort(edge, edge+cnt, cmp);int ans=0, num=0;for(int i=0; i<cnt; i++) {if(num==n-1) break;int a=find(edge[i].from), b=find(edge[i].to);if(a!=b) {unite(a, b);ans+=edge[i].w;num++;}}printf("%d\n", ans);return ;
}int main() {int n, cnt;while(scanf("%d", &n)!=EOF) {init(n);cnt=0;for(int i=1; i<=n; i++) {for(int j=1; j<=n; j++) {scanf("%d", &edge[cnt].w);edge[cnt].from=i;edge[cnt].to=j;cnt++;}}int q, a, b;scanf("%d", &q);while(q--) {scanf("%d %d", &a, &b);edge[cnt].from=a;edge[cnt].to=b;edge[cnt].w=0;cnt++;}kruskal(cnt, n);}return 0;
}

Kruskal 算法相关推荐

  1. 数据结构与算法(7-3)最小生成树(普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法)

    目录 一.最小生成树简介 二.普里姆算法(Prim) 1.原理 2.存储 2-1.图顶点和权: 2-3. 最小生成树: 3.Prim()函数 3-1.新顶点入树 3-2.保留最小权 3-3. 找到最小 ...

  2. 基本数据结构(图: 基本结构,DFS,prim算法, kruskal算法)

    #include <iostream> using namespace std; //约定: //1. 图是由很多节点(VERTEX)构成的, 因此图结构是由一个VERTEX的链表构成的, ...

  3. Kruskal算法 - C语言详解

    最小生成树 在含有n个顶点的连通图中选择n-1条边,构成一棵极小连通子图,并使该连通子图中n-1条边上权值之和达到最小,则称其为连通网的最小生成树.  例如,对于如上图G4所示的连通网可以有多棵权值总 ...

  4. 【数据结构】最小生成树 Prim算法 Kruskal算法

    最小生成树应用场景: 假设以下场景,有一块木板,板上钉上一些钉子,这些钉子可以由一些细绳连接起来.假设每个钉子可以通过一根或者多根细绳连接起来,那么一定存在这样得情况,即用最少的细绳把所有的钉子连接起 ...

  5. ds图—最小生成树_Java: Kruskal算法生成最小生成树(邻接矩阵)

    Java: Kruskal算法生成最小生成树(邻接矩阵): package 输出: Kruskal=36: (E,F) (C,D) (D,E) (B,F) (E,G) (A,B) 分析: Java: ...

  6. 生成树的概念,最小生成树Prim算法 Kruskal算法

    求解最小生成树可以用Prim算法 Kruskal算法

  7. Kruskal算法构造最小生成树

    问题[描述算法问题,首选形式化方式(数学语言),其次才是非形式化方式(日常语言)] 在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即),而 w(u, v) ...

  8. Prim算法和Kruskal算法求最小生成树

    Prim算法 连通分量是指图的一个子图,子图中任意两个顶点之间都是可达的.最小生成树是连通图的一个连通分量,且所有边的权值和最小. 最小生成树中,一个顶点最多与两个顶点邻接:若连通图有n个顶点,则最小 ...

  9. 生成随机数放入整型数组怎么判断有没有重复_图的应用(1)-连通图的最小生成树(Prim算法和Kruskal算法)...

    连通图的生成树: 是一个极小的连通图,它含有图中全部的N个顶点,但是只足以构成一颗树的N-1条边. 必须满足三个条件: 图是连通图: 图中包含了N个结点 图中边的数量等于N-1条. 连通图生成树的判断 ...

  10. python【数据结构与算法】最小生成树之Kruskal算法

    我们用现在来模拟一下Kruskal算法,下面给出一个无向图B,我们使用Kruskal来找无向图B的最小生成树. 首先,我们将所有的边都进行从小到大的排序.排序之后根据贪心准则,我们选取最小边(A,D) ...

最新文章

  1. 机器学习模型调优总结!
  2. python之路--嵌套函数、匿名函数、高阶函数。函数的递归
  3. 结果集(ResultSet)用法
  4. mysql年份_【数据库_Mysql】查询当前年份的sql
  5. Apache的简单应用
  6. 7个管理和优化网站资源的 Python 工具
  7. cntk-notes
  8. MYSQL的函数有哪些?(4.2时间与日期函数)
  9. 微软开源基于云的生理学研究工具
  10. [即将举行的网络研讨会]对Kubernetes进行故障排除:您需要具备的7个关键组件
  11. 一个java类运行时从哪个方法开始_Java的应用程序是从类中的
  12. showModalDialog页面
  13. jstree中文api文档_还在用 Swagger(丝袜哥)生成接口文档?我推荐你试试它。。。...
  14. 软件测试学习指南(更新中)
  15. webstorm控制台中文乱码解决
  16. Java创建mysql触发器
  17. R语言使用t.test函数执行t检验获取总体平均值的置信区间(默认输出结果包括95%置信水平的置信区间)
  18. 如何利用巨象指纹浏览器在twitter上找到精准客户
  19. (转) Exploring How Cache Coherency Accelerates Heterogeneous Compute
  20. Java以毫秒为单位返回秒表记录的流逝时间(即求一个程序段的运行时间)

热门文章

  1. java中折半查找思想_java折半查找法
  2. 复习效率低?这个学习方法,你学会了吗?
  3. 不同颜色的LED不能直接并联
  4. 【CloudXNS码农提示】为何CNAME和MX不能共存?
  5. 玩转Ubuntu(配置FTP工具之SFTP Net Drive Free)
  6. PR基础学习(三) 载入编辑素材
  7. iOS基础-数据解析方法初步总结-(XML,JSON欢迎指正)
  8. 使用chrome模拟微信内置浏览器
  9. 二手车交易价格预测----:模型结果融合
  10. mysql 中替换回车换行