https://www.luogu.com.cn/problem/P1991
AC代码:
/*
我将玫瑰藏于身后,晚风也变得温柔,
借着皎洁的月光,许下这一世与你白头。
那是独属于我们的花田
浪漫在原野上肆意狂奔
你摘下我头上的落叶
然后一起藏进树上看星火夜幕
多年后再闻见玫瑰森香
我想我还会想起那处山谷 和那个你
候鸟南飞,万河归海,不远千里.
你的过去我没有参与,你的未来我陪你!
地球之所以是圆的,就是为了让迷路的人重逢.
爱是天时地利的迷信,原来你也在这里!
我会用尽全力去爱你,接受你的坏脾气.
容忍的小任性,分享你的一切.
无论是开心,还是难过....
给自己喜欢的人留一句话吧:
*/
#include<bits/stdc++.h>
using namespace std;
const int N=1e6;
struct yqyqyq{//yq!yq!yq!yq!永远滴神!
double x,y;
}A[N];//存点坐标
struct wlwlwl{//wulong哥哥太帅辣!
int u,v;
double c;
}B[N];//存连接的两节点和边长
int C[N];//存每个节点的父节点
bool cmp1(const wlwlwl&x,const wlwlwl&y)//结构体从小到大排序
{
return x.c<y.c;
}
int find(int x)//寻找祖宗
{
if(C[x]!=x) C[x]=find(C[x]);
return C[x];
}
int main()
{
int S,P;
scanf("%d%d",&S,&P);
for(int i=1;i<=P;i++) scanf("%lf%lf",&A[i].x,&A[i].y);
//用double防止精度缺失?(我也不确定)
for(int i=1;i<=P;i++) C[i]=i;//初始化父节点
int d=0;
for(int i=1;i<=P;i++)
{
for(int j=1+i;j<=P;j++)//j>i避免重复存边
{
d++;
B[d].u=i;
B[d].v=j;
B[d].c=sqrt((A[i].x-A[j].x)*(A[i].x-A[j].x)+(A[i].y-A[j].y)*(A[i].y-A[j].y));
//两点距离公式
}
}
sort(B+1,B+d+1,cmp1);//结构体排序
int sum=0;
for(int i=1;i<=d;i++){
int a=find(B[i].u);
int b=find(B[i].v);
if(a!=b){//连接两节点
C[a]=b;
sum++;
}
if(sum==P-S){
//最小生成树P-1条边
//有S个卫星电话,S-1条边
//所以要P-1-(S-1)条边
//即P-S条边
printf("%.2lf\n",B[i].c);//保留两位小数
return 0;
}
}
}