【bzoj1821】[JSOI2010]Group 部落划分 Group

题目大意:要求把n个点分成m块,使得每一块之间的距离的最小值最大

 

n^2枚举所有点之间距离

然后sort一下

并查集维护连通关系

 

一开始e[]开MAXN然后WA了测了4ms,然后开MAXN<<2又WA不过测了24ms,再开MAXN<<5又WA测了68ms

,又开MAXN<<10 TLE了= =,最后MAXN<<8过了。。。(是不是很无聊??)

 

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std; 
 
#define MAXN 10010
 
struct Node
{
    int x,y;
    double z;
}e[MAXN<<8];
 
int k;
 
int n,m;
int ans;
 
int x[MAXN],y[MAXN];
int f[MAXN];
 
int cmp(Node a,Node b)
{
    return a.z<b.z;
}
 
double work(int a,int b)
{
    int r1=x[a]-x[b];
    int r2=y[a]-y[b];
    return sqrt(r1*r1+r2*r2);
}
 
int find(int x)
{
    return f[x]==x ? x : f[x]=find(f[x]);
}
 
int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)
        f[i]=i;
    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++)
        {
            k++;
            e[k].x=i;
            e[k].y=j;
            e[k].z=work(i,j);
        }
    sort(e+1,e+k+1,cmp);
    for (int i=1;i<=k;i++)
    {
        int r1=find(e[i].x);
        int r2=find(e[i].y);
        if (r1==r2)
            continue;
        if (n==m)
        {
            printf("%.2lf\n",e[i].z);
            break;     
        }
        if (r1>r2)
            swap(r1,r2);
        f[r1]=r2;
        n--;
    }
    return 0;
}

  

posted @ 2016-03-25 20:56  Yangjiyuan  阅读(195)  评论(0编辑  收藏  举报