无线通讯网

题目描述 Description###

国防部计划用无线网络连接若干个边防哨所。2种不同的通讯技术用来搭建无线网络;每个边防哨所都要配备无线电收发器;有一些哨所还可以增配卫星电话。
任意两个配备了一条卫星电话线路的哨所(两边都拥有卫星电话)均可以通话,无论他们相距多远。而只通过无线电收发器通话的哨所之间的距离不能超过\(D\) ,这是受收发器的功率限制。收发器的功率越高,通话距离D会更远,但同时价格也会更贵。
收发器需要统一购买和安装,所以全部哨所只能选择安装一种型号的收发器。换句话说,每一对哨所之间的通话距离都是同一个\(D\)
你的任务是确定收发器必须的最小通话距离\(D\) ,使得每一对哨所之间至少有一条通话路径(直接的或者间接的)。

输入描述 Input Description###

第1行:2个整数\(S(1<=S<=100)\) 和$ P(S<P<=500)$ ,\(S\) 表示可安装的卫星电话的哨所数,\(P\) 表示边防哨所的数量。
接下里$ P$ 行,每行描述一个哨所的平面坐标$ (x,y)$ ,以$ km \(为单位,整数,\) 0<=x,y<=10000$ 。

输出描述 Output Description###

第1行:1个实数$D $,表示无线电收发器的最小传输距离。精确到小数点后两位。

样例输入 Sample Input###

2 4
 0 100
 0 300
 0 600
 150 750

样例输出 Sample Output###

212.13

数据范围及提示 Data Size & Hint###

对于100%的数据 $1<=S<=100,S<P<=500 $

之前的一些废话###

题解###

二分之后并查集判是否可行。

代码###

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
#define mem(a,b) memset(a,b,sizeof(a))
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
	return x*f;
}
const int maxn=510;
const double eps=1e-8;
int s,n,x[maxn],y[maxn],f[maxn],all;
double L=0.0,R=25000.0;
int getf(int x){return x==f[x] ? x : f[x]=getf(f[x]);}
void merge(int a,int b)
{
	int x=getf(a),y=getf(b);
	if(x!=y)f[x]=y,all--;
}
double dis(int a,int b,int c,int d){return sqrt((double)(a-c)*(a-c)+(b-d)*(b-d));}
bool judge(double index)
{
	all=n;
	for(int i=1;i<=n;i++)f[i]=i;
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=n;j++)
	    	if(dis(x[i],y[i],x[j],y[j])<=index)merge(i,j);
	int cnt=0;
	for(int i=1;i<=n;i++)if(i==getf(i))cnt++;
	return cnt<=s;
}
int main()
{
	s=read();n=read();
	for(int i=1;i<=n;i++)x[i]=read(),y[i]=read();
	while(R-L>eps)
	{
		double mid=(L+R)/2.0;
		if(judge(mid))R=mid;
		else L=mid;		
	}
	printf("%.2lf",L);
	return 0;
}
 

总结###

posted @ 2017-10-23 21:52  小飞淙的云端  阅读(292)  评论(0编辑  收藏  举报