题目大意

给定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 最小生成树的更多相关文章

  1. Kruskal 最小生成树算法

    对于一个给定的连通的无向图 G = (V, E),希望找到一个无回路的子集 T,T 是 E 的子集,它连接了所有的顶点,且其权值之和为最小. 因为 T 无回路且连接所有的顶点,所以它必然是一棵树,称为 ...

  2. 贪心算法(2)-Kruskal最小生成树

    什么是最小生成树? 生成树是相对图来说的,一个图的生成树是一个树并把图的所有顶点连接在一起.一个图可以有许多不同的生成树.一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n ...

  3. Prim和Kruskal最小生成树

    标题: Prim和Kruskal最小生成树时 限: 2000 ms内存限制: 15000 K总时限: 3000 ms描述: 给出一个矩阵,要求以矩阵方式单步输出生成过程.要求先输出Prim生成过程,再 ...

  4. [算法系列之二十七]Kruskal最小生成树算法

    简单介绍 求最小生成树一共同拥有两种算法,一个是就是本文所说的Kruskal算法,还有一个就是Prime算法. 在具体解说Kruskal最小生成树算法之前,让我们先回想一下什么是最小生成树. 我们有一 ...

  5. poj 2031Building a Space Station(几何判断+Kruskal最小生成树)

    /* 最小生成树 + 几何判断 Kruskal 球心之间的距离 - 两个球的半径 < 0 则说明是覆盖的!此时的距离按照0计算 */ #include<iostream> #incl ...

  6. CSP 地铁修建 Kruskal (最小生成树+并查集)

    问题描述 A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力,A市决定在1号到n号枢纽间修建一条地铁. 地铁由很多段隧道组成,每段隧道连接两个交通枢纽.经过勘探,有m段隧道作为候选,两个交通 ...

  7. vijos P1234口袋的天空(Kruskal)(最小生成树)

    P1234口袋的天空 小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空. 有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖. 描述 给你云朵的个数N,再给你M个关系,表示哪些云朵 ...

  8. POJ 1789 Truck History (Kruskal最小生成树) 模板题

    Description Advanced Cargo Movement, Ltd. uses trucks of different types. Some trucks are used for v ...

  9. 并查集和kruskal最小生成树算法

    并查集 先定义 int f[10100];//定义祖先 之后初始化 for(int i=1;i<=n;++i) f[i]=i; //初始化 下面为并查集操作 int find(int x)//i ...

随机推荐

  1. ztree获取选中节点

    $(document).ready(function(){ $.fn.zTree.init($("#treeDemo"), setting, zNodes); }); functi ...

  2. ISP图像质量调节介绍

    ISP(Image Signal Processor),即图像处理,主要作用是对前端图像传感器输出的信号做后期处理,主要功能有线性纠正.噪声去除.坏点去除.内插.白平衡.自己主动曝光控制等.依赖于IS ...

  3. sql查看所有表大小的方法

    sql查看所有表大小的方法. 代码: declare @id int ) declare @pages int declare @dbname sysname ,) ,) ,) create tabl ...

  4. 安卓开发学习2-官方例子Accelerometer

    1.使用WakeLock防止屏幕被锁住,如果用户自己锁住屏幕,下次再开的时候还会重置一下,防止被锁. 2.SimulationView接收传感器事件,并且绘制.它实现SensorEventListen ...

  5. centos 搭建nginx

    yum install wget yum install gcc-c++ yum -y install pcre prec-devel yum -y install zlib zlib-devel y ...

  6. 流式布局的使用方法--Masonry

    http://www.jq22.com/demo/masonry/ 范例 css部分 body { background-color: #c7cad0; } .post_box { backgroun ...

  7. 解决eclipse启动tomcat报错:Could not load the Tomcat server configuration at \Servers\Tomcat v6.0 Server at localhost-config. The Servers project is closed.

    报错信息已经说的很清楚了:The Servers project is closed.如图 打开即可: 另外,如果你修改了Servers project的name(比如说把这里的Servers改成了X ...

  8. Redis的字典扩容与ConcurrentHashMap的扩容策略比较

    本文介绍Redis的字典(是种Map)扩容与ConcurrentHashMap的扩容策略,并比较它们的优缺点. (不讨论它们的实现细节) 首先Redis的字典采用的是一种‘’单线程渐进式rehash‘ ...

  9. 【pywin32总结】

    #下面是必备的#注意!所有方法后面都要加括号()!!! import win32com from win32com.client import Dispatch,constants w = win32 ...

  10. 【sql绕过】Bypass waf notepad of def

    文章是通过阅读<[独家连载]我的WafBypass之道 (SQL注入篇)>写的阅读笔记. Waf的类型 1.云waf云waf通常是CDN包含的waf,DNS在解析的时候要解析到cdn上面制 ...