• BZOJ 1821 Group 部落划分 并查集


    题目链接:

    https://www.lydsy.com/JudgeOnline/problem.php?id=1821

    题目大意:

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

    思路:

    按边排序,从小到大合并,直到恰好连通块数目为k是的边就是最大的最小距离。

     1 #include<bits/stdc++.h>
     2 #define IOS ios::sync_with_stdio(false);//不可再使用scanf printf
     3 #define Max(a, b) ((a) > (b) ? (a) : (b))//禁用于函数,会超时
     4 #define Min(a, b) ((a) < (b) ? (a) : (b))
     5 #define Mem(a) memset(a, 0, sizeof(a))
     6 #define Dis(x, y, x1, y1) ((x - x1) * (x - x1) + (y - y1) * (y - y1))
     7 #define MID(l, r) ((l) + ((r) - (l)) / 2)
     8 #define lson ((o)<<1)
     9 #define rson ((o)<<1|1)
    10 #define Accepted 0
    11 #pragma comment(linker, "/STACK:102400000,102400000")//栈外挂
    12 using namespace std;
    13 inline int read()
    14 {
    15     int x=0,f=1;char ch=getchar();
    16     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    17     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    18     return x*f;
    19 }
    20 typedef long long ll;
    21 const int maxn = 1000 + 10;
    22 const int MOD = 1000000007;//const引用更快,宏定义也更快
    23 const int INF = 1e9 + 7;
    24 const double eps = 1e-6;
    25 
    26 struct node
    27 {
    28     ll x, y;
    29     node(){}
    30     node(ll x, ll y):x(x), y(y){}
    31 }a[maxn];
    32 struct edge
    33 {
    34     int u, v;
    35     ll w;
    36     edge(){}
    37     edge(int u, int v, ll w):u(u), v(v), w(w){}
    38     bool operator < (const edge& a)const
    39     {
    40         return w < a.w;
    41     }
    42 };
    43 vector<edge>e;
    44 ll F(int i, int j)
    45 {
    46     return (a[i].x - a[j].x) * (a[i].x - a[j].x) + (a[i].y - a[j].y) * (a[i].y - a[j].y);
    47 }
    48 int pa[maxn];
    49 int Find(int x)
    50 {
    51     return x == pa[x] ? x : pa[x] = Find(pa[x]);
    52 }
    53 int main()
    54 {
    55     int n, k;
    56     scanf("%d%d", &n, &k);
    57     for(int i = 1; i <= n; i++)scanf("%lld%lld", &a[i].x, &a[i].y);
    58     for(int i = 1; i <= n; i++)
    59         for(int j = i + 1; j <= n; j++)
    60             e.push_back(edge(i, j, F(i, j)));
    61     sort(e.begin(), e.end());
    62     for(int i = 1; i <= n; i++)pa[i] = i;
    63     for(int i = 0; i < e.size(); i++)
    64     {
    65         if(Find(e[i].u) != Find(e[i].v))
    66         {
    67             if(n > k)
    68             {
    69                 n--;//连通块数目减一
    70                 pa[Find(e[i].u)] = Find(e[i].v);
    71             }
    72             else
    73             {
    74                 printf("%.2lf
    ", sqrt(1.0 * e[i].w));
    75                 break;
    76             }
    77         }
    78     }
    79     return Accepted;
    80 }
  • 相关阅读:
    MySQL的注入过程
    nmap 扫描器的功能
    用dvwa演示带有用户令牌(user_token)的暴力破解
    在python中安装requests模块
    如何发现struts2漏洞
    vs2017的主题颜色的配置
    在vs上开发linux c++
    linux主机之间的SSH链接
    verilog 实用的小技巧
    verilog 实现DDS
  • 原文地址:https://www.cnblogs.com/fzl194/p/9696384.html
Copyright © 2020-2023  润新知