poj_2349 Kruskal 最小生成树
题目大意
给定N个点的坐标,这N个点之间需要进行通讯。通讯方式可以采用卫星通信或无线通信,若两点之间采用为卫星通信,则两点之间的距离无限制,若采用无线通讯,则两点之间的距离不能大于某个值D。
现有s台卫星通信设备可以分配给这N个点,其余的点之间必须使用无线通信。要让这N个点中所有的点都能相互通信,则合理分配s台卫星通信设备,可以使得采用无线通信的那些点之间的距离D达到一个最小值,求该最小值。
题目分析
让所有的点之间均能通信,为一个生成树结构。题目就是求出这N个点的最小生成树。然后将最小生成树分成S个割集,割集之间采用卫星通信,割集之内采用无线通信,求出割集之内点之间的最大值即可。
可以证明,割集之内的点距离的最大值的最小值为最小生成树的N-1条边从大到小排列后第S个边长。采用kruskal算法解决。
实现(c++)
#include<stdio.h>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
#define MAX_NODE 505
//点的数据结构
struct Point{
int x;
int y;
};
vector<Point> gPoints; //边的数据结构
struct Edge{
int from;
int to;
double dist;
Edge(int f, int t, double d) :
from(f), to(t), dist(d){};
};
vector<Edge> gEdges; //计算两点之间的距离
double Dist(const Point& p1, const Point& p2){
return sqrt(1.0*(p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y));
} //用并查集来判断加入一条边是否会构成环
int gRoot[MAX_NODE];
int GetRoot(int c){
if (gRoot[c] != c){
gRoot[c] = GetRoot(gRoot[c]);
}
return gRoot[c];
}
bool SameRoot(int c1, int c2){
int p1 = GetRoot(c1);
int p2 = GetRoot(c2);
return p1 == p2;
} void Union(int c1, int c2){
int p1 = GetRoot(c1);
int p2 = GetRoot(c2);
gRoot[p1] = p2;
}
//用于对边进行排序
bool Compare(const Edge& e1, const Edge& e2){
return e1.dist < e2.dist;
} double Kruskal(int s, int n){
double result;
for (int i = 0; i < n; i++){
gRoot[i] = i;
}
sort(gEdges.begin(), gEdges.end(), Compare); //无向图的边只存储了 从序号较小的节点指向序号较大的节点
int count = 0;
for (int i = 0; i < gEdges.size(); i++){
Edge& e = gEdges[i];
if (SameRoot(e.from, e.to))
continue; count++;
if (count == n - s){
//从最小生成树中的n-1条边,去掉最大的s-1条边(因为有s个卫星站,相当于s个点,则s-1条边)
//,剩下的n-1-s条边中,最大的边长即为所求
result = e.dist;
return result;
} Union(e.to, e.from);
//gRoot[gRoot[e.to]] = gRoot[e.from]; //注意合并的时候,将 to 的根更新为 from的根。因为所有的边只存储了从小序号指向大序号
}
return 0;
} int main(){
int cas, s, p;
Point point;
scanf("%d", &cas);
while (cas--){
scanf("%d %d", &s, &p);
gEdges.clear();
gPoints.clear();
for (int i = 0; i < p; i++){
scanf("%d %d", &point.x, &point.y);
for (int j = 0; j < i; j++){
double dist = Dist(point, gPoints[j]);
gEdges.push_back(Edge(j, i, dist));
}
gPoints.push_back(point);
}
double result = Kruskal(s, p);
printf("%.2lf\n", result);
}
return 0;
}
poj_2349 Kruskal 最小生成树的更多相关文章
- Kruskal 最小生成树算法
对于一个给定的连通的无向图 G = (V, E),希望找到一个无回路的子集 T,T 是 E 的子集,它连接了所有的顶点,且其权值之和为最小. 因为 T 无回路且连接所有的顶点,所以它必然是一棵树,称为 ...
- 贪心算法(2)-Kruskal最小生成树
什么是最小生成树? 生成树是相对图来说的,一个图的生成树是一个树并把图的所有顶点连接在一起.一个图可以有许多不同的生成树.一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n ...
- Prim和Kruskal最小生成树
标题: Prim和Kruskal最小生成树时 限: 2000 ms内存限制: 15000 K总时限: 3000 ms描述: 给出一个矩阵,要求以矩阵方式单步输出生成过程.要求先输出Prim生成过程,再 ...
- [算法系列之二十七]Kruskal最小生成树算法
简单介绍 求最小生成树一共同拥有两种算法,一个是就是本文所说的Kruskal算法,还有一个就是Prime算法. 在具体解说Kruskal最小生成树算法之前,让我们先回想一下什么是最小生成树. 我们有一 ...
- poj 2031Building a Space Station(几何判断+Kruskal最小生成树)
/* 最小生成树 + 几何判断 Kruskal 球心之间的距离 - 两个球的半径 < 0 则说明是覆盖的!此时的距离按照0计算 */ #include<iostream> #incl ...
- CSP 地铁修建 Kruskal (最小生成树+并查集)
问题描述 A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力,A市决定在1号到n号枢纽间修建一条地铁. 地铁由很多段隧道组成,每段隧道连接两个交通枢纽.经过勘探,有m段隧道作为候选,两个交通 ...
- vijos P1234口袋的天空(Kruskal)(最小生成树)
P1234口袋的天空 小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空. 有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖. 描述 给你云朵的个数N,再给你M个关系,表示哪些云朵 ...
- POJ 1789 Truck History (Kruskal最小生成树) 模板题
Description Advanced Cargo Movement, Ltd. uses trucks of different types. Some trucks are used for v ...
- 并查集和kruskal最小生成树算法
并查集 先定义 int f[10100];//定义祖先 之后初始化 for(int i=1;i<=n;++i) f[i]=i; //初始化 下面为并查集操作 int find(int x)//i ...
随机推荐
- C语言错误处理方法、C++异常处理方法(throw, try, catch)简介
一.C语言错误处理方法 1.返回值(if … else语句判断错误) 2.errno(linux 系统调用) 3.goto语句(函数内局部跳转) 4.setjmp.longjmp(Do not use ...
- SeeSharpTools.JXI.DSP.Spectrum 使用
_spectrumTask.Average.Mode = SeeSharpTools.JXI.DSP.Spectrum.SpectrumAverageMode.PeakHold; // NoAvera ...
- tp请求和响应
一.请求参数 use think\Request; 1.获取方法如下: http://w.tp.com/index/index/index/user/AAA $this->request-> ...
- spring in action 7.2 小结
1 对于二进制文件上传功能的实现.在spring中使用multipart来处理,处理方式有两种. CommonsMultipartResolver:使用Jakarta Commons FileUplo ...
- Atitit.js javascript异常处理机制与java异常的转换.js exception process Voae
Atitit.js javascript异常处理机制与java异常的转换.js exception processVoae 1. 1. javascript异常处理机制 1 2. 2. Web前后台异 ...
- jquery经常使用操作
页面load方法 $().ready(function() { }) div隐藏操作 // div是否隐藏 function isHideMenu(){ return $("#menuCon ...
- 动态更新highcharts数据
<!doctype html> <html> <head> <script type="text/javascript" src=&quo ...
- 管道相关函数(1)-pipe
定义: int pipe(int filedes[2]); 表头文件: #include<unistd.h> 说明: pipe()会建立管道, 并将文件描述词由参数filedes数组返回. ...
- Tomcat7中开启gzip压缩功能的配置方法
使用gzip压缩可以减少数据传输大小,加快网页加载速度.很多大站都开启了gzip压缩,不过也有很多网站并没有开启gzip压缩,上次看了一篇文章说开启gzip压缩后对搜索引擎不友好,但从带宽和流量的角度 ...
- PHP中把stdClass Object转array的几个方法
方法一: 复制代码代码如下: //PHP stdClass Object转array function object_array($array) { if(is_object($array)) { $ ...