模板题,学习一下最小生成树的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. ES6中的高阶函数:如同 a => b => c 一样简单

    作者:Sequoia McDowell 2016年01月16日 ES6来啦!随着越来越多的代码库和思潮引领者开始在他们的代码中使用ES6,以往被认为是"仅需了解"的ES6特性变成了 ...

  2. 判断一个字符串在至多删除k个字符后是否为回文串

    转自: http://www.careercup.com/question?id=6287528252407808 问题描述: A k-palindrome is a string which tra ...

  3. asp.net网站中添加百度地图功能

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head ...

  4. 2014多校第四场1005 || HDU 4901 The Romantic Hero (DP)

    题目链接 题意 :给你一个数列,让你从中挑选一些数组成集合S,挑另外一些数组成集合T,要求是S中的每一个数在原序列中的下标要小于T中每一个数在原序列中下标.S中所有数按位异或后的值要与T中所有的数按位 ...

  5. spring 注入失败

    最近发现autowired注入总是失败. 总结下: 一个bean 要么都通过getter setter加上配置文件配置注入. <bean id="temResetService&quo ...

  6. Hadoop 在windows 上伪分布式的安装过程

    第一部分:Hadoop 在windows 上伪分布式的安装过程 安装JDK 1.下载JDK        http://www.oracle.com/technetwork/java/javaee/d ...

  7. Arraylist和Vector的区别与HashMap和Hashtable的区别

    1.ArrayList和HashMap都是线程异步的,所以它们的特点是效率高,但是安全性低: 2.Vector和Hashtable都是线程同步的,所以它们的特点是效率低,但是安全性高.

  8. 利用反射完成初级万能DAO

    一.目标 利用反射完成初级万能DAO 二.注意 1.Field[] fi = clazz.getDeclaredFields(); for(Field ff : fi){ ff.setAccessib ...

  9. Knight's Trip---hdu3766(马走日求最小走的步数)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3766 给你一个x ,y 求出从(0,0)位置到达需要的最小步数每次只能走日型: 下图为暴力bfs得到的 ...

  10. [软件]XAMPP错误解决

    // 错误1  (在运行安装包时候出现) // 错误2 1. 找到这个文件 这个文件  要将 config.inc.php 中 $cfg['Servers'][$i]['host'] = ’local ...