题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1162

意义:给出一些点,用线问使所有点直接或间接连通,需要多长;

思路:裸最小生成树;

法1:

prim算法:MST(Minimum Spanning Tree,最小生成树)问题有两种通用的解法,Prim算法就是其中之一,它是从点的方面考虑构建一颗MST,大致思想是:设图G顶点集合为U,首先任意选择图G中的一点作为起始点a,将该点加入集合V,再从集合U-V中找到另一点b使得点b到V中任意一点的权值最小,此时将b点也加入集合V;以此类推,现在的集合V={a,b},再从集合U-V中找到另一点c使得点c到V中任意一点的权值最小,此时将c点加入集合V,直至所有顶点全部被加入V,此时就构建出了一颗MST。因为有N个顶点,所以该MST就有N-1条边,每一次向集合V中加入一个点,就意味着找到一条MST的边。(这短话复制的别人的,感觉写的蛮好的)

prim算法就是从待选点集中依次选出距离已选点集中距离最小的点加入已选点集中;

代码:

 #include <iostream>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <stdio.h>
#define MAXN 100+10
#define INF 9999999999
using namespace std; int n, tag[MAXN];
double mp[MAXN][MAXN], low[MAXN]; double prime(void){
memset(tag, , sizeof(tag)); //×××标记数组清 0
int s=;
double cnt=;
for(int i=; i<=n; i++){ //×××从点 1 开始
low[i]=mp[s][i];
}
for(int i=; i<=n; i++){
double min=INF;
for(int j=; j<=n; j++){ //×××找到未添加点中到以添加点中距离最近的点即当前要添加的点
if(!tag[j]&&min>low[j]){
min=low[j];
s=j;
}
}
cnt+=min; //***本题中不存在不能连同的情况,所以不需要加 if(min>=INF) return -1
tag[s]=;
for(int j=; j<=n; j++){
if(!tag[j]&&low[j]>mp[s][j]){ //×××更新low数组
low[j]=mp[s][j];
}
}
}
return cnt;
} int main(void){
while(~scanf("%d", &n)){
pair<double, double> p[MAXN];
for(int i=; i<=n; i++){
scanf("%lf%lf", &p[i].first, &p[i].second);
}
for(int i=; i<=n; i++){
for(int j=; j<=n; j++){
mp[i][j]=sqrt((p[j].first-p[i].first)*(p[j].first-p[i].first)+(p[j].second-p[i].second)*(p[j].second-p[i].second));
}
}
double ans=prime();
printf("%.2lf\n", ans);
}
return ;
}

法2:

kruscal算法:

将图中边按其权值由小到大的次序顺序选取,若选边后不形成回路,则保留作为一条边,若形成回路则除去.依次选够(n-1)条边,即得最小生成树.(n为顶点数)

代码:

 #include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#define MAXN 10000+10
using namespace std; struct node{
int x, y;
double weight;
}map[MAXN]; int m, n, pre[MAXN]; bool cmp(node a, node b){
return a.weight < b.weight;
} int find(int x){
while(pre[x]!=x){
x=pre[x];
}
return x;
} double join(node a){
int px=find(a.x);
int py=find(a.y);
if(px!=py){
pre[px]=py;
return a.weight;
}else{
return ; //××××若成环则返回 0
}
} double kruskal(void){
for(int i=; i<=n; i++){
pre[i]=i;
}
double cnt=;
sort(map, map+m, cmp);
for(int i=; i<m; i++){
cnt+=join(map[i]);
}
return cnt;
} int main(void){
while(~scanf("%d", &n)){
pair<double, double> p[MAXN];
for(int i=; i<=n; i++){
scanf("%lf%lf", &p[i].first, &p[i].second);
}
int k=;
for(int i=; i<=n; i++){
for(int j=i+; j<=n; j++){
double cnt=sqrt((p[i].first-p[j].first)*(p[i].first-p[j].first)+(p[i].second-p[j].second)*(p[i].second-p[j].second));
map[k].x=i;
map[k].y=j;
map[k].weight=cnt;
k++;
}
}
m=k;
double ans=kruskal();
printf("%.2lf\n", ans);
}
return ;
}

hdu1162(最小生成树 prim or kruscal)的更多相关文章

  1. hdu1162(最小生成树 prim or kruscal模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1162 意义:给出一些点,用线问使所有点直接或间接连通,需要多长: 思路:裸最小生成树: 法1: pri ...

  2. 数据结构代码整理(线性表,栈,队列,串,二叉树,图的建立和遍历stl,最小生成树prim算法)。。持续更新中。。。

    //归并排序递归方法实现 #include <iostream> #include <cstdio> using namespace std; #define maxn 100 ...

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

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

  4. 最小生成树Prim算法(邻接矩阵和邻接表)

    最小生成树,普利姆算法. 简述算法: 先初始化一棵只有一个顶点的树,以这一顶点开始,找到它的最小权值,将这条边上的令一个顶点添加到树中 再从这棵树中的所有顶点中找到一个最小权值(而且权值的另一顶点不属 ...

  5. 转载:最小生成树-Prim算法和Kruskal算法

    本文摘自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html 最小生成树-Prim算法和Kruskal算法 Prim算 ...

  6. 最小生成树Prim

    首先解释什么是最小生成树,最小生成树是指在一张图中找出一棵树,任意两点的距离已经是最短的了. 算法要点: 1.用book数组存放访问过的节点. 2.用dis数组保存对应下标的点到树的最近距离,这里要注 ...

  7. 最小生成树—prim算法

    最小生成树prim算法实现 所谓生成树,就是n个点之间连成n-1条边的图形.而最小生成树,就是权值(两点间直线的值)之和的最小值. 首先,要用二维数组记录点和权值.如上图所示无向图: int map[ ...

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

    Prim算法(使用visited数组实现) Prim算法求最小生成树的时候和边数无关,和顶点树有关,所以适合求解稠密网的最小生成树. Prim算法的步骤包括: 1. 将一个图分为两部分,一部分归为点集 ...

  9. 最小生成树 Prim Kruskal

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

随机推荐

  1. CMake Error: your CXX compiler: "" was not found

    [root@amax src]# cmake . -- The CXX compiler identification is unknown CMake Error at /usr/local/sha ...

  2. MongoDB的基本使用(二)

    上一个文档说明了如何搭建一个Windows端MongoDB服务器,下面将简单介绍MongoDB的基本操作命令. 1. show dbs : 显示所有数据库 2. use bochao : 使用boch ...

  3. BZOJ1012——[JSOI2008]最大数maxnumber

    1.题目大意:求末尾L个数的最大值,强制在线 2.分析:这个拿线段树可以直接水过,然后我写了一个 维护单调栈, 二分求最大值的短代码,手懒.... #include <cstdio> #i ...

  4. 简单易懂的crontab设置工具集

    导读 在上一篇文章中,我介绍了crontab的配置文件以及如何设置定时任务,对于偶尔用一次crontab的同学而言,可能遗忘配置语法会很快,这里我向大家推荐几个在线设置crontab任务的网站. ge ...

  5. PYTHON seek()tell()语句

    print(f.tell()) # 显示当前位置 f.seek(0) #回到某一起点

  6. OpenCV人形检测Hog

    #include "iostream" #include "queue" using namespace std; #include "opencv2 ...

  7. Python自动化之socketserver模块

    1 动态导入模块 import importlib aa = importlib.import_module("lib1.aa") //lib跟当前模块不是一个目录,aa是lib下 ...

  8. swing复制文本框内容

    Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); //得到系统剪贴板 String text = jTex ...

  9. String和StringBuffer的转换

    从String到StringBuffer: StringBuffer sb = New StringBuffer("abcd");从StringBuffer到String: Str ...

  10. dango foreign key 指定被引用模型的字段

    用 to_field pool_no = models.ForeignKey('SimCardPool', verbose_name=u'卡池编号', db_column='pool_no', to_ ...