最小生成树之Kruskal
模板题,学习一下最小生成树的Kruskal算法
对于一个连通网(连通带权图,假定每条边上的权均为大于零的实数)来说,每棵树的权(即树中所有边的权值总和)也可能不同
具有权最小的生成树称为最小生成树
生成树:
- 无向连通图的边的集合
- 无回路
- 连接所有的点
最小:
- 所有边的权值之和最小
n个顶点的树有n-1条边
时间复杂度:O(ElogE)
对于稀疏图来说
按所给的边的权值从小到大排序,如果该边不与已经选的边形成环就选择它
这里用并查集来实现
第i条边的端点放在u、v数组中,权值保存在w中
这里用的是间接排序,也就是排的是每条边的序号,放在rank数组中
下面是两道模板题:
HDU 1863 畅通工程
1 //#define LOCAL 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 7 const int maxn = 5000; 8 int u[maxn], v[maxn], w[maxn], parent[maxn], rank[maxn]; 9 int m, n; 10 11 bool cmp(const int i, const int j) 12 { 13 return (w[i] < w[j]); 14 } 15 16 int GetParent(int a) 17 { 18 return parent[a] == a ? a : parent[a] = GetParent(parent[a]); 19 } 20 21 int kruskal(void) 22 { 23 int cnt = 0, weight = 0; 24 for(int i = 0; i < m; ++i) 25 { 26 int edge = rank[i]; 27 int x = GetParent(u[edge]); 28 int y = GetParent(v[edge]); 29 if(x != y) 30 { 31 weight += w[edge]; 32 ++cnt; 33 parent[x] = y; 34 } 35 } 36 if(cnt < n - 1) weight = 0; 37 return weight; 38 } 39 40 int main(void) 41 { 42 #ifdef LOCAL 43 freopen("1863in.txt", "r", stdin); 44 #endif 45 46 47 while(scanf("%d%d", &m, &n) == 2 && m) 48 { 49 for(int i = 0; i < m; ++i) 50 scanf("%d%d%d", &u[i], &v[i], &w[i]); 51 for(int i = 0; i < n; ++i) parent[i] = i; 52 for(int i = 0; i < m; ++i) rank[i] = i; 53 sort(rank, rank + m, cmp); 54 int ans = kruskal(); 55 if(ans) 56 printf("%d\n", ans); 57 else 58 printf("?\n"); 59 } 60 return 0; 61 }
代码君一
POJ 1861 Network
感觉这道题略坑啊,它并没有说是多组输入啊,而且输出的第一个数是边里面的最大权值啊,数组开了1000多开小了啊,还有各种小错误啊。Orz
好吧,这些都是我的错误,上来就套模板,没有好好读题
1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 8 const int maxn = 1000 + 10; 9 int v[maxn], u[maxn], r[maxn], p[maxn], w[maxn], path[maxn]; 10 int n, m, cnt, ans; 11 12 int Find(int a) 13 { 14 return p[a] == a ? a : p[a] = Find(p[a]); 15 } 16 17 bool cmp(const int i, const int j) 18 { 19 return (w[i] < w[j]); 20 } 21 22 void Kruskal(void) 23 { 24 cnt = 0, ans = -1; 25 for(int i = 0; i < m; ++i) 26 { 27 int edge = r[i]; 28 int x = Find(u[edge]); 29 int y = Find(v[edge]); 30 if(x != y) 31 { 32 ans = max(ans, w[edge]); 33 p[x] = y; 34 path[cnt++] = i; 35 } 36 } 37 } 38 39 void OutPut(void) 40 { 41 printf("%d\n%d\n", ans, cnt); 42 for(int i = 0; i < cnt; ++i) 43 printf("%d %d\n", u[r[path[i]]], v[r[path[i]]]); 44 } 45 46 int main(void) 47 { 48 #ifdef LOCAL 49 freopen("1861in.txt", "r", stdin); 50 #endif 51 52 while(scanf("%d%d", &n, &m) == 2) 53 { 54 for(int i = 0; i < m; ++i) 55 scanf("%d%d%d", &u[i], &v[i], &w[i]); 56 for(int i = 0; i < n; ++i) p[i] = i; 57 for(int i = 0; i < m; ++i) r[i] = i; 58 sort(r, r + m, cmp); 59 Kruskal(); 60 OutPut(); 61 } 62 63 return 0; 64 }
代码君二
POJ 2560 Freckles
题意:给出n个点的坐标,求最小生成树的长度。奇怪的是G++没过,C++却过了
1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #include <cmath> 7 using namespace std; 8 9 const int maxn = 5000 + 10; 10 struct Node 11 { 12 double x, y; 13 }pos[maxn]; 14 15 int u[maxn], v[maxn], r[maxn], p[maxn]; 16 double w[maxn]; 17 18 bool cmp(const int i, const int j) 19 { 20 return (w[i] < w[j]); 21 } 22 23 int Find(int a) 24 { 25 return p[a] == a ? a : p[a] = Find(p[a]); 26 } 27 28 double Kruskal(int cnt) 29 { 30 double ans = 0.0; 31 for(int i = 0; i < cnt; ++i) 32 { 33 int edge = r[i]; 34 int x = Find(u[edge]); 35 int y = Find(v[edge]); 36 if(x != y) 37 { 38 ans += w[edge]; 39 p[x] = y; 40 } 41 } 42 return ans; 43 } 44 45 int main(void) 46 { 47 #ifdef LOCAL 48 freopen("2560in.txt", "r", stdin); 49 #endif 50 51 int n, cnt; 52 while(scanf("%d", &n) == 1) 53 { 54 for(int i = 0; i < n; ++i) p[i] = i; 55 for(int i = 0; i < n; ++i) 56 scanf("%lf %lf", &pos[i].x, &pos[i].y); 57 cnt = 0; 58 for(int i = 1; i < n; ++i) 59 for(int j = 0; j < i; ++j) 60 { 61 u[cnt] = i; 62 v[cnt] = j; 63 r[cnt] = cnt; 64 w[cnt++] = sqrt((pos[i].x-pos[j].x)*(pos[i].x-pos[j].x) + (pos[i].y-pos[j].y)*(pos[i].y-pos[j].y)); 65 } 66 sort(r, r + cnt, cmp); 67 printf("%.2lf\n", Kruskal(cnt)); 68 } 69 70 return 0; 71 }
代码君三
转载于:https://www.cnblogs.com/AOQNRMGYXLMV/p/3958599.html
最小生成树之Kruskal相关推荐
- 最小生成树之Kruskal算法
图片描述 算法思想 采用贪婪策略,连续的按最小的权选择边,并且当边不产生圈时就把它作为取定的边 算法思路 问题出现 1.怎样选择最小权的边 用个排序算法 2.怎样判断加入的边是否会产生圈 (用到不相交 ...
- 最小生成树的Kruskal算法实现
最近在复习数据结构,所以想起了之前做的一个最小生成树算法.用Kruskal算法实现的,结合堆排序可以复习回顾数据结构.现在写出来与大家分享. 最小生成树算法思想:书上说的是在一给定的无向图G = (V ...
- 最小生成树:Kruskal算法 和 Prim算法(第23章)
武侠: 飞雪连天射白鹿,笑书神侠倚碧鸳. --金庸十四著作 飞狐外传 .雪山飞狐 .连城诀 .天龙八部 .射雕英雄传 .白马啸西风 .鹿鼎记 .笑傲江湖 .书剑恩仇录 .神雕侠侣 .侠客岛 .倚天屠龙 ...
- 数据结构------最小生成树之Kruskal算法
盛年不重来,一日难再晨.及时当勉励,岁月不待人. <杂诗>陶渊明 目录 前言 一.Kruskal的几何思维 二.使用步骤 1.核心思想 2.全部测试代码 总结 前言 最小生成树算法有两种一 ...
- 最小生成树的Kruskal算法-详解
最小生成树的Kruskal算法 一. 什么是最小生成树 1.1 最小生成树定义: 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边.最 ...
- kruskal算法c语言,最小生成树之Kruskal算法
上一篇文章中提到了最小生成树的Prim算法,这一节继续探讨一下最小生成树的Kruskal算法.什么是最小生成树算法上文已经交代过了,所以我们直接从Kruskal的步骤开始介绍. 1.Kruskal算法 ...
- ds图—最小生成树_Java: Kruskal算法生成最小生成树(邻接矩阵)
Java: Kruskal算法生成最小生成树(邻接矩阵): package 输出: Kruskal=36: (E,F) (C,D) (D,E) (B,F) (E,G) (A,B) 分析: Java: ...
- 最小生成树(kruskal、prim、最小生成森林问题、严格次小生成树)
整理的算法模板合集: ACM模板 目录 一.kruskal算法 二.prim算法 三.Boruvka算法 四.生成森林问题(K颗树) 五.最小生成树的唯一性 六.严格次小生成树 LCA优化的次小生成树 ...
- 最小生成树(kruskal+prime)
kruskal模板: #include<iostream> #include<bits/stdc++.h> using namespace std;const int MAXN ...
最新文章
- 【C#】枚举_结构体_数组
- BCH的创新已打破比特币的共识效应
- linux ssh和sftp区别,使用 SSH 和 SFTP 协议
- 在ubuntu下安装free pascal
- MYSQL主从同步故障一例及解决过程
- Fix chrome 下flash crash的问题
- Laravel Query Builder 复杂查询案例:子查询实现分区查询 partition by
- Spring中注解注入bean和配置文件注入bean
- 流计算技术实战 - 超大维表问题
- 实现一个符合标准的Promise
- MongoDB 自动分片 auto sharding
- 使用ServletContextListener关闭Redisson连接
- idea解决Untracked Files Prevent Merge问题
- 僵尸网络 DDoS 攻击活动分析
- bootstrap 5 表单验证
- SQLyog连接不上
- Win10无法使用内置管理员账户打开应用解决办法
- 第四次面试----华数电力科技有限公司
- Windows7 Embedded Standard x64更新代码80072EFE解决方法
- java需要用到英语_javaSE常用的英语单词
热门文章
- linux操作系统上课,Linux操作系统使用的文件系统是
- mysql聚合函数count用法_MySQL中聚合函数count的使用和性能优化技巧
- antd 函数组件_React - 组件:函数组件
- 如何加速云原生数据应用?这个开源项目备受关注
- 云原生 DevOps 的 5 步升级路径
- 阿里云 OpenYurt 成为 CNCF 沙箱项目,加速原生 Kubernetes 边缘场景全覆盖
- 初探云原生应用管理(二): 为什么你必须尽快转向 Helm v3
- APP元素事件操作API
- Python中字典的介绍以及常用操作
- python元类的使用_Python 元类使用讲解