hdu1162(最小生成树 prim or kruscal)
题目链接: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)的更多相关文章
- hdu1162(最小生成树 prim or kruscal模板)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1162 意义:给出一些点,用线问使所有点直接或间接连通,需要多长: 思路:裸最小生成树: 法1: pri ...
- 数据结构代码整理(线性表,栈,队列,串,二叉树,图的建立和遍历stl,最小生成树prim算法)。。持续更新中。。。
//归并排序递归方法实现 #include <iostream> #include <cstdio> using namespace std; #define maxn 100 ...
- 邻接矩阵c源码(构造邻接矩阵,深度优先遍历,广度优先遍历,最小生成树prim,kruskal算法)
matrix.c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include < ...
- 最小生成树Prim算法(邻接矩阵和邻接表)
最小生成树,普利姆算法. 简述算法: 先初始化一棵只有一个顶点的树,以这一顶点开始,找到它的最小权值,将这条边上的令一个顶点添加到树中 再从这棵树中的所有顶点中找到一个最小权值(而且权值的另一顶点不属 ...
- 转载:最小生成树-Prim算法和Kruskal算法
本文摘自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html 最小生成树-Prim算法和Kruskal算法 Prim算 ...
- 最小生成树Prim
首先解释什么是最小生成树,最小生成树是指在一张图中找出一棵树,任意两点的距离已经是最短的了. 算法要点: 1.用book数组存放访问过的节点. 2.用dis数组保存对应下标的点到树的最近距离,这里要注 ...
- 最小生成树—prim算法
最小生成树prim算法实现 所谓生成树,就是n个点之间连成n-1条边的图形.而最小生成树,就是权值(两点间直线的值)之和的最小值. 首先,要用二维数组记录点和权值.如上图所示无向图: int map[ ...
- 最小生成树Prim算法和Kruskal算法
Prim算法(使用visited数组实现) Prim算法求最小生成树的时候和边数无关,和顶点树有关,所以适合求解稠密网的最小生成树. Prim算法的步骤包括: 1. 将一个图分为两部分,一部分归为点集 ...
- 最小生成树 Prim Kruskal
layout: post title: 最小生成树 Prim Kruskal date: 2017-04-29 tag: 数据结构和算法 --- 目录 TOC {:toc} 最小生成树Minimum ...
随机推荐
- mongodb certification
又偷懒 也有学到不少东西 这个东西算是小结啦 给2013年的碌碌无为挽回点面子 哈哈~
- NFS工作原理及配置文件详解
nfs工作原理流程 如上图所示,当访问程序通过NFS客户端向NFS服务端存取文件时,其请求数据流程如下几点: 1.首先用户访问网站程序,由程序在NFS客户端上发出NFS文件存取功能 ...
- Codeforces Round #292 (Div. 2) C. Drazil and Factorial
题目链接:http://codeforces.com/contest/515/problem/C 给出一个公式例如:F(135) = 1! * 3! * 5!; 现在给你一个有n位的数字a,让你求这样 ...
- BZOJ2730——[HNOI2012]矿场搭建
bzoj2730 & world final 2011 H 1.题目大意:就是有一个无向图,让你在里面选择点,使得,无论哪个点没了以后,其他的点都能到达你选择的任何一个点,输出最少 选择几个点 ...
- leetcode 82. Remove Duplicates from Sorted List II
Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numb ...
- Unity3D获取Andorid设备返回键,主页键等功能
在Unity开发中捕捉Android的常用事件其实很简单 在新建的脚本文件中就加入: 比如: // 返回键 if ( Application.platform == RuntimePlatform.A ...
- mysql 将指定列的浮点数转化为整数
mysql 将指定列的浮点数转化为整数: update A set B = cast(B as decimal(10,0)) -- 或者 update A set B = round(B,0) 例 ...
- RouterOS首次打开网页强制跳转
网上极少有关于RouterOS的第一次打开网页强制跳转主页的方法,大多数都方法是将浏览某个域名的IP地址跳转到自己的主页,这种方法有时会失效.还有一种方法就是当用户用80端口连接时,抓取源地址到地址列 ...
- 关于ubuntukylin安装后界面中英文混杂的问题
起因 一直使用的是ubuntu原版的系统,ubuntukylin出来后也没用使用过.一次去其论坛逛了一圈之后决定使用一下. 安装后的截面和ubuntu原版的差不多,还是挺漂亮的. 但是有一个问题是,安 ...
- ubuntu 14.04 对exfat的支持
sudo apt-get install exfat-utils exfat-fuse sudo reboot