还是用kruskal 算法,把模板改动一下就好了
本质就是张图,当成所有哨所都互通,排序各哨所间的距离。卫星电话不限距离,所以只要考虑(P-S)个哨所,排序后选(P-S)个哨所中最大的距离(即最小传输距离D),保证所有哨所连通(即接上(P-S)条边)。
#include<bits/stdc++.h>
using namespace std;
const int P=505;
int s,p;//卫星电话数,哨所数
int parent[P];
double D;//表示无线电收发器的最小传输距离,精确到小数点后两位
struct node
{
double x,y;//哨所坐标
}node[P];
struct Edge
{
int p1,p2;//两个哨所
double len;//距离
}edge[P*P];
inline double dis(int i,int j)//计算哨所间距离
{
double distance;
distance=sqrt( pow(node[i].x-node[j].x,2) + pow(node[i].y-node[j].y,2) );
return distance;
}
inline bool cmp(Edge a,Edge b)
{
return a.len<b.len;
}
inline int find_root(int x)//寻找根结点
{
int x_root=x;
while(parent[x_root]!=-1)
{
x_root=parent[x_root];
}
return x_root;
}
int main()
{
cin>>s>>p;
for(register int i=1;i<=p;i++)//初始化
{
parent[i]=-1;
}
for(register int i=1;i<=p;i++)
{
cin>>node[i].x>>node[i].y;
}
int k=0;
for(register int i=1;i<=p;i++)//利用双重循环算出所有哨所相互间距离
{
for(register int j=i+1;j<=p;j++)
{
k++;
edge[k].p1=i;
edge[k].p2=j;
edge[k].len=dis(i,j);
}
}
sort(edge+1,edge+1+k,cmp);//排序
int cnt=p-s;
for(register int i=1;i<=k,cnt>0;i++)
{
int x_root=find_root(edge[i].p1);
int y_root=find_root(edge[i].p2);
if(x_root!=y_root)
{
parent[y_root]=x_root;
cnt--;
D=max(D,edge[i].len);
}
}
printf("%.2lf",D);
return 0;
}