平面上有N个部落,使划分成K个居住点后,最近的两个居住点之间的距离最远。两个部落的距离,定义为部落中距离最近的那两个居住点的距离。求这个距离。
将完全图的边按照距离从小到大排序,选中边的两端用并查集并起来,第N-K+1条边的长度即为答案.
这个题目不需要二分,贪心比较巧妙
#include <bits/stdc++.h> #define LL long long #define clr(x,i) memset(x,i,sizeof(x)) using namespace std; const int N=1005; struct Edge{ int u,v; double dist; friend bool operator <(Edge a,Edge b){ return a.dist<b.dist; } }e[N*N*2]; int n,K,tot,fa[N]; double x[N],y[N]; inline double Dis(int a,int b) { return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b])); } inline void Add(int u,int v) { e[++tot].u=u;e[tot].v=v;e[tot].dist=Dis(u,v); } int find(int v) { return fa[v]==v ? v : fa[v]=find(fa[v]); } int main() { scanf("%d%d",&n,&K); for(int i=1;i<=n;i++) scanf("%lf%lf",&x[i],&y[i]); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)if(i!=j) Add(i,j); sort(e+1,e+tot+1); for(int i=1;i<=n;i++)fa[i]=i; int cnt=0; for(int i=1;i<=tot;i++) { int x=find(e[i].u),y=find(e[i].v); if(x!=y){ cnt++;fa[x]=y; if(cnt==n-K+1){ printf("%.2lf",e[i].dist); break; } } } return 0; }