zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Linux平台不同解压缩命令的使用方法
    poj 1274 The Perfact Stall
    Experience Design for Sexable Forum
    JavaScript中的Array对象方法调用
    iOS9适配小结
    [Servlet&amp;JSP] HttpSession会话管理
    Android中的跨进程通信方法实例及特点分析(一):AIDL Service
    OpenCV——PS滤镜算法之Spherize 球面化(凸出效果)
    《Effective Modern C++》翻译--条款4:了解怎样查看推导出的类型
    Android开发系列之ListView
  • 原文地址:https://www.cnblogs.com/fzl194/p/9696384.html
Copyright © 2011-2022 走看看