# 无线通讯网
## 题目描述
国防部计划用无线网络连接若干个边防哨所。2 种不同的通讯技术用来搭建无线网络;
每个边防哨所都要配备无线电收发器;有一些哨所还可以增配卫星电话。
任意两个配备了一条卫星电话线路的哨所(两边都有卫星电话)均可以通话,无论他们相距多远。而只通过无线电收发器通话的哨所之间的距离不能超过 D,这是受收发器的功率限制。收发器的功率越高,通话距离 D 会更远,但同时价格也会更贵。
收发器需要统一购买和安装,所以全部哨所只能选择安装一种型号的收发器。换句话说,每一对哨所之间的通话距离都是同一个 D。你的任务是确定收发器必须的最小通话距离 D,使得每一对哨所之间至少有一条通话路径(直接的或者间接的)。
## 输入格式
第一行,2 个整数 S 和 P,S 表示可安装的卫星电话的哨所数,P 表示边防哨所的数量。
接下里 P 行,每行两个整数 x,y 描述一个哨所的平面坐标 (x, y),以 km 为单位。
## 输出格式
第一行,1 个实数 D,表示无线电收发器的最小传输距离,精确到小数点后两位。
## 样例 #1
### 样例输入 #1
```
2 4
0 100
0 300
0 600
150 750
```
### 样例输出 #1
```
212.13
```
## 提示
### 数据范围及约定
- 对于 20% 的数据:P = 2,S = 1;
- 对于另外 20% 的数据:P = 4,S = 2;
- 对于 100% 的数据保证:1 ≤ S ≤ 100,S < P ≤ 500,0 ≤ x,y ≤ 10000。
解题思路
这道题的数据比较小,我们可以直接把每一个哨所之间距离给算出来,然后按距离从小到大排序,利用Kruskal 来生成树就行了(只要链接p-s个节点就行了,后面就可以用卫星电话了)。因为我们是从小到大来建立的,于是最后一个节点和前一个节点的距离就是最大距离。
代码
#include<bits/stdc++.h>
using namespace std;
int a[510],b[510];
int s,p,n;
struct ss
{int x;int y;double jl;
}g[510*510];
int j[510];
int j2[510];
int find1(int x)
{if(j[x]==x)return x;return j[x]=find1(j[x]);
}
int cmp(ss x,ss y)
{return x.jl<y.jl;
}
void unit(int x,int y)
{if((x=find1(x))==(y=find1(y))) return;if(j2[x]<j2[y]) j[x]=y;else if(j2[x]>j2[y]) j[y]=x;else{j[x]=y; j2[y]++;}
}
int main()
{int x,y,t=0;double min1;scanf("%d%d",&s,&p);for(x=1;x<=p;x++){scanf("%d%d",&a[x],&b[x]);j[x]=x;}for(x=1;x<=p;x++){for(y=1;y<=p;y++){g[++n].jl=sqrt((a[x]-a[y])*(a[x]-a[y])+(b[x]-b[y])*(b[x]-b[y]));g[n].x=x;g[n].y=y;}}sort(g+1,g+n+1,cmp);for(x=1;x<=n;x++){if(t==p-s)break;if(find1(g[x].x)!=find1(g[x].y)){unit(g[x].x,g[x].y);t++;min1=g[x].jl;}}printf("%.2lf",min1);return 0;
}