BZOJ-1821 [JSOI2010]Group 部落划分 Group(最小生成树)
题目描述
给出二维平面上的 \(n(1\leq n\leq 1000)\) 个点,把它们划分成 \(k\) 组,使某两个不同组的点的距离的最小值尽可能大。
分析
优先合并边权小的边,每次合并连通块数量都会减少一,连通块数量等于 \(k\) 时退出,此时剩下的边中边权最小的边就是答案。
代码
#include<bits/stdc++.h>
using namespace std;
int fa[1010],x[1010],y[1010],cnt;
struct Edge
{
int u,v;
double w;
}edge[1010*1010];
bool cmp(Edge A,Edge B)
{
return A.w<B.w;
}
int get(int x)
{
if(x!=fa[x])
return fa[x]=get(fa[x]);
return x;
}
int main()
{
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)
{
scanf("%d %d",&x[i],&y[i]);
fa[i]=i;
}
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
edge[++cnt].u=i;
edge[cnt].v=j;
edge[cnt].w=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}
}
sort(edge+1,edge+1+cnt,cmp);
for(int i=1;i<=cnt;i++)
{
int fx=get(edge[i].u),fy=get(edge[i].v);
if(fx!=fy)
{
if(n==k)
{
printf("%.2lf\n",edge[i].w);
return 0;
}
fa[fx]=fy;
n--;
}
}
return 0;
}
posted on 2020-11-28 15:51 DestinHistoire 阅读(51) 评论(0) 编辑 收藏 举报