【题目描述】
国防部计划用无线网络连接若干个边防哨所。2种不同的通讯技术用来搭建无线网络;每个边防哨所都要配备无线电收发器;有一些哨所还可以增配卫星电话。
任意两个配备了一条卫星电话线路的哨所(两边都拥有卫星电话)均可以通话,无论他们相距多远。而只通过无线电收发器通话的哨所之间的距离不能超过D,这是受收发器的功率限制。收发器的功率越高,通话距离D会更远,但同时价格也会更贵。
收发器需要统一购买和安装,所以全部哨所只能选择安装一种型号的收发器。换句话说,每一对哨所之间的通话距离都是同一个D。
你的任务是确定收发器必须的最小通话距离D,使得每一对哨所之间至少有一条通话路径(直接的或者间接的)。
【输入格式】 wireless.in
第1行:2个整数S(1<=S<=100)和P(S<P<=500),S表示可安装的卫星电话的哨所数,P表示边防哨所的数量。
接下里P行,每行描述一个哨所的平面坐标(x,y),以km为单位,整数,0<=x,y<=10000。
【输出格式】 wireless.out
第1行:1个实数D,表示无线电收发器的最小传输距离。精确到小数点后两位。
【样例输入】
2 4
0 100
0 300
0 600
150 750
【样例输出】
212.13
数据范围
对于20%的数据 P=2,S=1
对于另外20%的数据 P=4,S=2
对于100%的数据 1<=S<=100,S<P<=500
题意是有n个点在坐标系中,可以选m个点,把它们之间的距离全改成0,求所有点两两之间的距离的最大值
原来以为这是点和点之间的关系,最小生成树好像不太行。
但是数据太小,所以我用的二分+并查集
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } struct p{ int x,y; }point[1001]; struct edge{ int x,y; double v; }e[300000]; inline bool cmp(edge a,edge b) {return a.v<b.v;} inline double dist(p a,p b) { int xx=abs(a.x-b.x),yy=abs(a.y-b.y); return sqrt(xx*xx+yy*yy); } int fa[1001]; inline int getfa(int x) { if (fa[x]==x) return x; else return fa[x]=getfa(fa[x]); } int n,m,tot; double ans; inline bool jud(int x) { int piece=m,s,t; for (int i=1;i<=m;i++) fa[i]=i; for (int i=1;i<=x;i++) { s=getfa(e[i].x); t=getfa(e[i].y); if (s!=t) { piece--; fa[s]=t; } } if (piece<=n) return 1; return 0; } int main() { freopen("wireless.in","r",stdin); freopen("wireless.out","w",stdout); n=read();m=read(); for(int i=1;i<=m;i++) { point[i].x=read();point[i].y=read(); for (int j=1;j<i;j++) { e[++tot].x=i; e[tot].y=j; e[tot].v=dist(point[i],point[j]); } } sort(e+1,e+tot+1,cmp); int l=0,r=tot; while (l<=r) { int mid=(l+r)>>1; if (jud(mid)){ans=e[mid].v;r=mid-1;} else{l=mid+1;} } printf("%.2lf",ans); }
——by zhber,转载请注明来源