模板题,学习一下最小生成树的Kruskal算法

对于一个连通网(连通带权图,假定每条边上的权均为大于零的实数)来说,每棵树的权(即树中所有边的权值总和)也可能不同

具有权最小的生成树称为最小生成树

生成树:

  • 无向连通图的边的集合
  • 无回路
  • 连接所有的点

最小:

  • 所有边的权值之和最小

n个顶点的树有n-1条边

时间复杂度:O(ElogE)

对于稀疏图来说

按所给的边的权值从小到大排序,如果该边不与已经选的边形成环就选择它

这里用并查集来实现

第i条边的端点放在u、v数组中,权值保存在w中

这里用的是间接排序,也就是排的是每条边的序号,放在rank数组中

下面是两道模板题:

HDU 1863 畅通工程

 //#define LOCAL
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std; const int maxn = ;
int u[maxn], v[maxn], w[maxn], parent[maxn], rank[maxn];
int m, n; bool cmp(const int i, const int j)
{
return (w[i] < w[j]);
} int GetParent(int a)
{
return parent[a] == a ? a : parent[a] = GetParent(parent[a]);
} int kruskal(void)
{
int cnt = , weight = ;
for(int i = ; i < m; ++i)
{
int edge = rank[i];
int x = GetParent(u[edge]);
int y = GetParent(v[edge]);
if(x != y)
{
weight += w[edge];
++cnt;
parent[x] = y;
}
}
if(cnt < n - ) weight = ;
return weight;
} int main(void)
{
#ifdef LOCAL
freopen("1863in.txt", "r", stdin);
#endif while(scanf("%d%d", &m, &n) == && m)
{
for(int i = ; i < m; ++i)
scanf("%d%d%d", &u[i], &v[i], &w[i]);
for(int i = ; i < n; ++i) parent[i] = i;
for(int i = ; i < m; ++i) rank[i] = i;
sort(rank, rank + m, cmp);
int ans = kruskal();
if(ans)
printf("%d\n", ans);
else
printf("?\n");
}
return ;
}

代码君一

POJ 1861 Network

感觉这道题略坑啊,它并没有说是多组输入啊,而且输出的第一个数是边里面的最大权值啊,数组开了1000多开小了啊,还有各种小错误啊。Orz

好吧,这些都是我的错误,上来就套模板,没有好好读题

 //#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = + ;
int v[maxn], u[maxn], r[maxn], p[maxn], w[maxn], path[maxn];
int n, m, cnt, ans; int Find(int a)
{
return p[a] == a ? a : p[a] = Find(p[a]);
} bool cmp(const int i, const int j)
{
return (w[i] < w[j]);
} void Kruskal(void)
{
cnt = , ans = -;
for(int i = ; i < m; ++i)
{
int edge = r[i];
int x = Find(u[edge]);
int y = Find(v[edge]);
if(x != y)
{
ans = max(ans, w[edge]);
p[x] = y;
path[cnt++] = i;
}
}
} void OutPut(void)
{
printf("%d\n%d\n", ans, cnt);
for(int i = ; i < cnt; ++i)
printf("%d %d\n", u[r[path[i]]], v[r[path[i]]]);
} int main(void)
{
#ifdef LOCAL
freopen("1861in.txt", "r", stdin);
#endif while(scanf("%d%d", &n, &m) == )
{
for(int i = ; i < m; ++i)
scanf("%d%d%d", &u[i], &v[i], &w[i]);
for(int i = ; i < n; ++i) p[i] = i;
for(int i = ; i < m; ++i) r[i] = i;
sort(r, r + m, cmp);
Kruskal();
OutPut();
} return ;
}

代码君二

POJ 2560 Freckles

题意:给出n个点的坐标,求最小生成树的长度。奇怪的是G++没过,C++却过了

 //#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std; const int maxn = + ;
struct Node
{
double x, y;
}pos[maxn]; int u[maxn], v[maxn], r[maxn], p[maxn];
double w[maxn]; bool cmp(const int i, const int j)
{
return (w[i] < w[j]);
} int Find(int a)
{
return p[a] == a ? a : p[a] = Find(p[a]);
} double Kruskal(int cnt)
{
double ans = 0.0;
for(int i = ; i < cnt; ++i)
{
int edge = r[i];
int x = Find(u[edge]);
int y = Find(v[edge]);
if(x != y)
{
ans += w[edge];
p[x] = y;
}
}
return ans;
} int main(void)
{
#ifdef LOCAL
freopen("2560in.txt", "r", stdin);
#endif int n, cnt;
while(scanf("%d", &n) == )
{
for(int i = ; i < n; ++i) p[i] = i;
for(int i = ; i < n; ++i)
scanf("%lf %lf", &pos[i].x, &pos[i].y);
cnt = ;
for(int i = ; i < n; ++i)
for(int j = ; j < i; ++j)
{
u[cnt] = i;
v[cnt] = j;
r[cnt] = cnt;
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));
}
sort(r, r + cnt, cmp);
printf("%.2lf\n", Kruskal(cnt));
} return ;
}

代码君三

最小生成树之Kruskal的更多相关文章

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

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

  2. ZOJ 1203 Swordfish 旗鱼 最小生成树,Kruskal算法

    主题链接:problemId=203" target="_blank">ZOJ 1203 Swordfish 旗鱼 Swordfish Time Limit: 2 ...

  3. 经典问题----最小生成树(kruskal克鲁斯卡尔贪心算法)

    题目简述:假如有一个无向连通图,有n个顶点,有许多(带有权值即长度)边,让你用在其中选n-1条边把这n个顶点连起来,不漏掉任何一个点,然后这n-1条边的权值总和最小,就是最小生成树了,注意,不可绕成圈 ...

  4. 最小生成树 Prim Kruskal

    layout: post title: 最小生成树 Prim Kruskal date: 2017-04-29 tag: 数据结构和算法 --- 目录 TOC {:toc} 最小生成树Minimum ...

  5. 数据结构与算法--最小生成树之Kruskal算法

    数据结构与算法--最小生成树之Kruskal算法 上一节介绍了Prim算法,接着来看Kruskal算法. 我们知道Prim算法是从某个顶点开始,从现有树周围的所有邻边中选出权值最小的那条加入到MST中 ...

  6. HDU 1598 find the most comfortable road(最小生成树之Kruskal)

    题目链接: 传送门 find the most comfortable road Time Limit: 1000MS     Memory Limit: 32768 K Description XX ...

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

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

  8. 数据结构学习笔记05图(最小生成树 Prim Kruskal)

    最小生成树Minimum Spanning Tree 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边. 树: 无回路   |V|个顶 ...

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

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

随机推荐

  1. hadoop-ha QJM 架构部署

    公司之前老的hadoop集群namenode有单点风险,最近学习此链接http://www.binospace.com/index.php /hdfs-ha-quorum-journal-manage ...

  2. Assetbundle的杂七杂八

    使用Assetbundle时可能遇到的坑 一 24 十一郎未分类 No Comments 转自 http://www.unitymanual.com/blog-3571-132.html 1.Edit ...

  3. Sqli-labs less 63

    Less-63 和less62一致,我们只需要看到sql语句上 $sql="SELECT * FROM security.users WHERE id='$id' LIMIT 0,1&quo ...

  4. flashdevelop 开发技巧

    FlashDevelop用来编写AS3代码,Flash CS5用来编辑程序所需要的资源(图片,声音-),Flash CS5自带有Flex SDK,在目录 C:\Program Files\Adobe\ ...

  5. cf div2 236 D

    D. Upgrading Array time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  6. iScroll.js 用法参考

    本文原文链接:http://www.cnblogs.com/duanhuajian/archive/2013/04/08/3008323.html 概要 iScroll 4 这个版本完全重写了iScr ...

  7. java cookie

    public static void AddCookie(HttpServletResponse response, String key, String value) { Cookie cookie ...

  8. POJ 1947 Rebuilding Roads(树形DP)

    题目链接 题意 : 给你一棵树,问你至少断掉几条边能够得到有p个点的子树. 思路 : dp[i][j]代表的是以i为根的子树有j个节点.dp[u][i] = dp[u][j]+dp[son][i-j] ...

  9. jmeter线程组之间传递参数

    JMeter 变量作用域局限于所属线程.这样设计是经过深思熟虑的,目的是让测试线程能够独立运转.有时候用户可能需要在不同线程间(可能属于同一个线程组,也可能不属于同一个线程组)传递变量. 其中一种方法 ...

  10. skip list

    概述 Skip list是平衡树的一种替代的数据结构,但是和红黑树不相同的是,跳表对于树的平衡的实现是基于一种随机化的算法的,这样也就是说跳表的插入和删除的工作是比较简单的.并且是Redis.Leve ...