P4047 [JSOI2010]部落劃分(Kruskal)
思路:最小生成樹,因爲每個部落的距離定義爲每個部落中距離最近的兩個點的距離,所以我們可以建立一個最小生成樹,一個點代表第一個部落,因爲我們要分成個部落,所以需要刪去條邊,顯然貪心的刪去最小的條邊是最優的,所以答案就是第條邊。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
int n,k;
struct node{
int u,v;
double d;
bool operator<(const node& no)const{
return d<no.d;
}
}a[M];
int s[N],x[N],y[N];
int find(int x){
if(s[x]!=x) s[x]=find(s[x]);
return s[x];
}
int main(){
scanf("%d%d",&n,&k);
int id=0,cnt=0;
for(int i=1;i<=n;i++){
scanf("%d%d",&x[i],&y[i]);
for(int j=1;j<i;j++)
a[++id].u=i,a[id].v=j,a[id].d=hypot(x[i]-x[j],y[i]-y[j]);
s[i]=i;
}
sort(a+1,a+id+1);
double ans=0;
for(int i=1;i<=id;i++){
int fa=find(a[i].u),fb=find(a[i].v);
if(fa!=fb){
s[fa]=fb;
cnt++;
ans=a[i].d;
}
if(cnt==n-k+1) break;
}
printf("%.2lf\n",ans);
return 0;
}