DestinHistoire

 

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编辑  收藏  举报

导航