思路:我们把每两个部落之间的距离计算出来,每次选取部落距离最小的两个划分到一起,如果划分成功(两个部落本来不在一起),那么此时部落也减少了一个,当部落数等于目标数时,此时下一对距离最短的部落的距离是最短距离
第一次因为输出判断不太对wa了,QAQ,还是我太弱了
注释都在代码里了
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int n,k;
struct node{//这个结构体存坐标和编号
int x;
int y;
int cnt;
}d[10000010];
struct Struct{//存两个部落的距离和各自编号
double distance;
int x;
int y;
}S[10000010];
int pre[1010];
bool cmp(Struct a,Struct b){
return a.distance<b.distance;
}
void init(int n){//初始化函数
for(int i=1;i<=n;i++) pre[i]=i;
}
double dis(int x1,int y1,int x2,int y2){//计算两点距离
return sqrt(1.0*(x2-x1)*(x2-x1)+1.0*(y2-y1)*(y2-y1));
}
int find(int x){//查找的函数
if(pre[x]!=x) pre[x]=find(pre[x]);
return pre[x];
}
bool Union(int x,int y){//连接的函数
int a=find(x);
int b=find(y);
if(a!=b) {
pre[a]=b;
return true;
}
return false;
}
int main()
{
cin>>n>>k;
//输入
for(int i=1;i<=n;i++){
cin>>d[i].x>>d[i].y;
d[i].cnt=i;//部落编号从1到n
}
int t=1;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
S[t].distance=dis(d[i].x,d[i].y,d[j].x,d[j].y);//计算两两部落间的距离
S[t].x=i,S[t].y=j;//把两两部落的编号存进去
t++;
}
}
t--;//t是两两部落的数量
sort(S+1,S+1+t,cmp);//按距离排序
init(n);
int i;
for(i=1;i<=t;i++){
if(Union(S[i].x,S[i].y)) {//如果连接成功,部落数-1
n--;
}
if(n==k) break;
}
i++;//此时下一个不同部落的距离是最短距离,所以+1
while(i){
if(Union(S[i].x,S[i].y)) {//寻找下一个可以连接的部落,找到就输出
printf("%.2f",S[i].distance);
break;
}
i++;
}
return 0;
}