Sol:一个并查集的简单题,将边权从小到大排序,然后尽量让小边连的点放到一个集合中。
#include<bits/stdc++.h> #define N 1000005 using namespace std; struct ppp { int x,y,v; } a[500005]; bool cmp(ppp a,ppp b) { return a.v<b.v; } int f[1005],x[1005],y[1005],tot,n,k,xx,yy; int get(int x) { return f[x]==x?x:f[x]=get(f[x]); } int main() { scanf("%d%d",&n,&k); for (int i=1; i<=n; i++) scanf("%d%d",&x[i],&y[i]); for (int i=1; i<=n; i++) for (int j=i+1; j<=n; j++) { tot++; a[tot].x=i; a[tot].y=j; a[tot].v=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]); } sort(a+1,a+tot+1,cmp);//将边权从小到大排序 for (int i=1; i<=n; i++) f[i]=i; for (int i=1; i<=tot; i++) //取出边来,尽量让小边所连的点,放在同一个部落中 { xx=get(a[i].x); yy=get(a[i].y); if (xx!=yy) //最开始N个点分成N个集合,如果不在一个集合,则合并起来 //集合个数减少一个 { n--; f[xx]=yy; if (n<k) //这里理解清楚,当集合个数小于k时,则说明当前已分成了K个集合了 //当前的边就是答案了 { printf("%.2lf",sqrt(a[i].v)); return 0; } } } }
原文:https://www.cnblogs.com/cutemush/p/12461024.html