​传送门​

P4047 [JSOI2010]部落划分_#include

思路:

要使划分后有k坨部落,也就是要进行两两合并n-k次,合并后再找到最近两坨部落间的距离即为答案。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int inf = 0x3f3f3f3f;
struct node{
int a,b;
double t;
friend bool operator < (node a, node b)
{
return a.t > b.t;
}
};
priority_queue<node>q;
int x[1010],y[1010];
node now;
int f[1010];
int find(int x)
{
return f[x]==x?x:f[x]=find(f[x]);
}
int main()
{
int n,k;
cin>>n>>k;
for(int i = 1; i <= n; i++)f[i] = i;
for(int i = 1; i <= n; i++)
{
cin>>x[i]>>y[i];
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
if(i != j)
{
now.a = i;
now.b = j;
now.t = sqrt(pow(x[i]-x[j],2)+pow(y[i]-y[j],2));
q.push(now);
}
}
}
int cnt = 0;
double ans = 0x3f3f3f3f;
while(cnt <= n-k)
{
now = q.top();
q.pop();
if(find(now.a) != find(now.b))
{
cnt++;
// ans = min(ans,now.t);
f[find(now.a)] = find(now.b);
}
}
while(q.size())
{
now = q.top();
q.pop();
if(find(now.a) != now.b)
{
ans = now.t;
break;
}
}
printf("%0.2lf\n",ans);
}