7th 【并查集&&最小生成树】无线通讯网
来源:互联网 发布:mysql 等于符号 编辑:程序博客网 时间:2024/06/12 01:18
无线通讯网
【题目描述】:
国防部计划用无线网络连接若干个边防哨所。2种不同的通讯技术用来搭建无线网络;每个边防哨所都要配备无线电收发器;有一些哨所还可以增配卫星电话。
任意两个配备了一条卫星电话线路的哨所(两边都拥有卫星电话)均可以通话,无论他们相距多远。而只通过无线电收发器通话的哨所之间的距离不能超过D,这是受收发器的功率限制。收发器的功率越高,通话距离D会更远,但同时价格也会更贵。
收发器需要统一购买和安装,所以全部哨所只能选择安装一种型号的收发器。换句话说,每一对哨所之间的通话距离都是同一个D。
你的任务是确定收发器必须的最小通话距离D,使得每一对哨所之间至少有一条通话路径(直接的或者间接的)。
【输入描述】:
第1行:2个整数S 和P ,S表示可安装的卫星电话的哨所数,P表示边防哨所的数量。
接下里P行,每行描述一个哨所的平面坐标(x,y),以km为单位。
【输出描述】:
第1行:1个实数D,表示无线电收发器的最小传输距离。精确到小数点后两位。
【样例输入】:
2 40 1000 3000 600150 750
【样例输出】:
212.13
【时间限制、数据范围及描述】:
时间:1s 空间:64M
对于20%的数据 P=2,S=1
对于另外20%的数据 P=4,S=2
对于100%的数据 1<=S<=100,S<P<=500,0<=x,y<=10000
啦啦啦厉害了我们来看一下这题。
并查集的运用真的是很方便,我比较菜只能套模板。
在平面上有p个点,其实两两都可以相连,现在给你s次机会,免费连接两个点,问如何连接所有点,使得最长的边最短。
先介绍一种常用的算法,就是把所有点连起来使得边的权值和最小。(最小生成树)
我们每次选择一个最短的边,然后看看该边两端的端点,如果这两个点不在一个集合内,就把这两个点放入一个集合内(意为连起来)。如果在个集合内,说明这两个点之间已经相通,那么你这次的连接是不划算的,因为这条边长度比前面的所有边长度都长,替换任意一条边都是不合理的
那么求树的最小权值边也是这个道理。
按小到大的顺序排列,每次经过判断后连接两个点。
那么 来看一看我手画的扭捏的图。
首先 3-4这条边最短,那么连接3和4。
(所以 f[3]=3,f[4]=3,这里通过并查集把两个点放在了一个集合)
其次 选择2-5这条边 因为2和5不在一个集合,所以连接2和5
继续 选择1-2这条边 因为1和2不在一个集合,所以连接1和2
(因为2和5在一个集合,所以通过并查集可以将1,2,5变成一个集合)
继续 选择1-4这条边 因为1和4不在一个集合,所以连接1和4
(这样1,2,3,4,5都放在了一个集体)
接着 选择1-5这条边 因为1和5在一个集合,所以不连接。
(因为6>2且6>3)
最后 选择3-5这条边 因为3和5在一个集合,所以不连接。
这样就选择了一条最优的连接方式。
那么我们看一下这题。
其实我们排完序后无需连接完整的树,只要连接p-s次就可以了,因为后面的s个可以免费相连。
那么我们从小到大开始连接。如果两点在一个集合,就跳过该边即可。
这里的边是隐藏的,我们需要计算每两点的距离。
看一下
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath>using namespace std; int s,p;int a[505],b[505];int f[250005];struct edge{ int x,y;//边的起点和中点 double d; //边的长度 }e[250005];//结构体 double dis(int a,int b,int c,int d){ double lon=(double)(sqrt((a-c)*(a-c)+(b-d)*(b-d))); return lon; }//两点间的距离 int find(int x){ if(f[x]==x) return x; return f[x]=find(f[x]);} //查找点所在集合 int cmp(edge a,edge b){ return a.d<b.d; }int main() { freopen("test1.in","r",stdin); freopen("test1.out","w",stdout); cin>>s>>p; int k=0; for(int i=1;i<=p;i++) cin>>a[i]>>b[i]; for(int i=1;i<=p-1;i++) for(int j=i+1;j<=p;j++) { e[++k].x=i; e[k].y=j; e[k].d=dis(a[i],b[i],a[j],b[j]); } //开始生成每条边 for(int i=1;i<=250005;i++) f[i]=i; sort(e+1,e+k+1,cmp);//从小到大进行排序 int i,j,fx,fy; for(i=1,j=1;i<=p-s;j++){ //我们需要连接 p-s条边 fx=find(e[j].x);fy=find(e[j].y);//查找两点 if(fx!=fy){i++;//连接一次 f[fx]=fy;//合并 }} printf("%.2lf\n",e[j-1].d);//结束以后 j-1的值是i次全部连接完后最后一个数的下标。 //即为所有边的最大值 return 0; }
程序
- 7th 【并查集&&最小生成树】无线通讯网
- 最小生成树+并查集(洛谷P1991 无线通讯网)
- 洛谷1991 无线通讯网 最小生成树
- 无线通讯网——最小生成树
- 4th 【最小生成树&&并查集】征兵
- 无线通讯网_纪中3078_最小生成树
- 无线通讯网 纪中3078 最小生成树
- 洛谷 1991 无线通讯网 最小生成树 解题报告
- 并查集与最小生成树
- 并查集模版&最小生成树
- 最小生成树kruscal+并查集
- 并查集+最小生成树_HDU_1102
- bzoj1050(最小生成树 并查集)
- 最小生成树与并查集
- 最小生成树与并查集
- 最小生成树+并查集+ kruskal
- 并查集 最小生成树
- 最小生成树(并查集)
- 安装OpenJDK1.8
- Java中的Filter过滤器
- Python特性(十六):由生成器诱导的context manager
- 计蒜客 管家的忠诚(线段树水题)
- Unity游戏暂停之Update与FixedUpdate区别
- 7th 【并查集&&最小生成树】无线通讯网
- 17/06/25 STM32嵌入式编程->systick系统滴答时钟
- JavaScript面向对象(2)——创建对象的工厂模式与构造函数模式
- docker 使用总结
- Oracle限制性查询和数据排序
- 基于MDK的分散加载文件
- Java for Web学习笔记(六七):Service和Repository(2)抽象分层例子
- 技术团队管理--代码规范的制定与落地
- ReactNative接入微信API 接入支付宝支付