(贪心+最小生成树) bzoj 1821

1821: [JSOI2010]Group 部落划分 Group

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 1409  Solved: 678
[Submit][Status][Discuss]

Description

聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落之间则经常发生争斗。只是,这一切都成为谜团了——聪聪根本就不知道部落究竟是如何分布的。 不过好消息是,聪聪得到了一份荒岛的地图。地图上标注了N个野人居住的地点(可以看作是平面上的坐标)。我们知道,同一个部落的野人总是生活在附近。我们把两个部落的距离,定义为部落中距离最近的那两个居住点的距离。聪聪还获得了一个有意义的信息——这些野人总共被分为了K个部落!这真是个好消息。聪聪希望从这些信息里挖掘出所有部落的详细信息。他正在尝试这样一种算法: 对于任意一种部落划分的方法,都能够求出两个部落之间的距离,聪聪希望求出一种部落划分的方法,使靠得最近的两个部落尽可能远离。 例如,下面的左图表示了一个好的划分,而右图则不是。请你编程帮助聪聪解决这个难题。 

Input

第一行包含两个整数N和K(1<=N<=1000,1<k<=n),分别代表了野人居住点的数量和部落的数量。 接下来n行,每行包含两个正整数x,y,描述了一个居住点的坐标(0<="x," y<="10000)。" <="" div="">

Output

输出一行,为最优划分时,最近的两个部落的距离,精确到小数点后两位。

Sample Input

4 2
0 0
0 1
1 1
1 0

Sample Output

1.00

HINT

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<string>
using namespace std;
int n,k,a[1001][2],fa[1001];
double dist(int x,int y)
{
    return sqrt(double((a[x][0]-a[y][0])*(a[x][0]-a[y][0])+(a[x][1]-a[y][1])*(a[x][1]-a[y][1])));
}
struct node
{
    int x,y;
    double z;
}e[1000001];
bool cmp(node aa,node bb)
{
    return aa.z<bb.z;
}
int find(int x)
{
    if(x!=fa[x])
        fa[x]=find(fa[x]);
    return fa[x];
}
int main()
{
    int cnt;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&a[i][0],&a[i][1]);
        fa[i]=i;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            e[++cnt].x=i,e[cnt].y=j;
            e[cnt].z=dist(i,j);
        }
    }
    //printf("111\n");
    sort(e+1,e+1+cnt,cmp);
    //printf("222\n");
    for(int i=1;i<=cnt;i++)
    {
        int x,y,fx,fy;
        x=e[i].x,y=e[i].y;
        fx=find(x),fy=find(y);
        if(fx!=fy)
        {
            if(n>k)
            {
                n--;
                fa[fx]=fy;
            }
            else
            {
                printf("%.2f\n",e[i].z);
                return 0;
            }
        }
    }
    return 0;
}

  

时间: 2024-10-04 03:30:02

(贪心+最小生成树) bzoj 1821的相关文章

【JSOI2010】Group 部落划分 BZOJ 1821

1821: [JSOI2010]Group 部落划分 Group Time Limit: 10 Sec  Memory Limit: 64 MB     聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是 拉帮结派形成属于自己的部落,不同的部落之间则经常发生争斗.只是,这一切都成为谜团了——聪聪根本就不知道部落究竟是如何分布的. 不过好消息是,聪聪得到了一份荒岛的地图.地图上标注了N个野人居住的地点(可以看作是平面上的坐标).我们知道,同一个部

【BZOJ 1821】 [JSOI2010]Group 部落划分 Group

1821: [JSOI2010]Group 部落划分 Group Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 1353  Solved: 650 [Submit][Status][Discuss] Description 聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落之间则经常发生争斗.只是,这一切都成为谜团了--聪聪根本就不知道部落究竟是如何分布的.

BZOJ 1821 JSOI 2010 Group 部落划分 Group Kruskal

题目大意:给出平面上的一些点,现在要把这些点分成k组,求每组之间的距离的最小值的最大值. 思路:很水的题,只需要做一次最小生成树 ,然后去掉k-1条边,第k-2条边就是答案. CODE: #include <cmath> #include <cstdio> #include <iomanip> #include <cstring> #include <iostream> #include <algorithm> #define MAX

BZOJ 1821 [JSOI2010] Group 部落划分 Group

最小生成森林? 个人感觉跟最小生成树差不多.需要分成k个联通块,让联通块之间距离最大就让联通块内距离尽可能小.一颗最小生成树是N-1条边,分成k个块需要切k-1条,就是一个n-k条边的最小生成森林,然后Kruskal中的下一条边(第n-k+2条)就是答案了. #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #incl

【贪心】 BZOJ 3252:攻略

3252: 攻略 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 261  Solved: 90[Submit][Status][Discuss] Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏. 今天他得到了一款新游戏<XX半岛>,这款游戏有n个场景(scene),某些场景可以通过不同的选择支到达其他场景.所有场景和选择支构成树状结构:开始游戏时在根节点(共通线),

【贪心】bzoj 3709:[PA2014]Bohater

3709: [PA2014]Bohater Time Limit: 5 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 653  Solved: 220[Submit][Status][Discuss] Description 在一款电脑游戏中,你需要打败n只怪物(从1到n编号).为了打败第i只怪物,你需要消耗d[i]点生命值,但怪物死后会掉落血药,使你恢复a[i]点生命值.任何时候你的生命值都不能降到0(或0以下).请问是否存在一种打怪顺序

[CF959E] Mahmoud and Ehab and the xor-MST - 贪心,最小生成树

\(n\) 个点的完全图标号 \((0-n-1)\),\(i\) 和 \(j\) 连边权值为 \(i\ \textrm{XOR}\ j\),求 MST 的值 Solution 设 \(f[n]\) 表示点数为 \(n+1\) 时的答案,那么贪心地考虑,显然 \(f[0]=0, f[n]=f[n-1]+lowbit(n)\) 根据观察易得 \(f[n]=2f[n-1]+2^n-2^{n-1}\),同时由于 \(f[]\) 就是个 \(lowbit\) 的前缀和,满足可加性,所以直接对 \(n\)

ARC 076 D Built 贪心+最小生成树

题意:n个点(x,y) n<=1e5,在(a,b)-(c,d)连边cost为min(|a-c|,|b-d|),任意两个点连通的最小代价? 对于两点A,B 连接两条边 权值为|a-c|,|b-d|按x坐标排序 A,B,C三点 由于要求MST,多点联通时只可能用到相邻点的边,A-C的边不可能在MST中所以最多2(n-1)条边,跑MST即可. #include <bits/stdc++.h> using namespace std; typedef long long ll; const in

BZOJ 1821 JSOI2010 部落划分 Group Kruskal

题目大意:给定平面上的n个点,要求将这n个点划分为k个集合,使划分后任意两个集合中最近两点的距离的最大值最小,输出这个最小值 考虑这n个点之间所有的连边 我们要让长边保留 就尽量选取短边链接 于是就是求加入n-k条边的最小生成森林 由于输出下一个最小值 因此Kruskal加入第n-k+1条边时输出边权即可 #include <cmath> #include <cstdio> #include <cstring> #include <iomanip> #inc