zoukankan      html  css  js  c++  java
  • BZOJ 1604 [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居:队列 + multiset + 并查集【曼哈顿距离变形】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1604

    题意:

      平面直角坐标系中,有n个点(n <= 100000,坐标范围10^9)。

      给定r,当两个点的曼哈顿距离<=r时,认为这两个点在同一个“群”中。

      问你共有多少个群,以及点的数量最多的群有多少个点。

    题解:

      本题的核心在于:如何枚举一个点周围满足“曼哈顿距离<=r”的点。

      由于 曼哈顿距离 = |x1 - x2| + |y1 - y2|。

      x和y相互影响,不能单纯按x或y排序,枚举所有点总复杂度为O(N^2)。

      所以要用到曼哈顿距离的另一种形式:

        设X = x + y , Y = x - y

        d(曼哈顿距离) = max(|X1-X2|, |Y1-Y2|)

      将每个点的X = x + y,Y = x - y,这就将X与Y的关系分离开了。

      

      将所有点按X排序。

      当前考虑到点i。

      用一个队列(X升序),保证队列中的所有X满足要求,否则不断删去队首。

      用一个multiset(Y升序),找到i的前驱pre和后继suc,如果i与pre(或suc)的Y满足要求,则合并(并查集)。

      最后统计一下每个群就好了。

    AC Code:

      1 // |x1-x2| + |y1-y2|
      2 // | (x1+y1) - (x2+y2) |
      3 // | (x1-y1) - (x2-y2) |
      4 // X = x + y
      5 // Y = x - y
      6 // d = max(|X1-X2|, |Y1-Y2|) <= r
      7 #include <iostream>
      8 #include <stdio.h>
      9 #include <string.h>
     10 #include <algorithm>
     11 #include <set>
     12 #define MAX_N 100005
     13 #define INF 100000000
     14 
     15 using namespace std;
     16 
     17 struct Coor
     18 {
     19     int x;
     20     int y;
     21     int idx;
     22     Coor(int _x,int _y,int _idx)
     23     {
     24         x=_x;
     25         y=_y;
     26         idx=_idx;
     27     }
     28     Coor(){}
     29     friend bool operator < (const Coor &a,const Coor &b)
     30     {
     31         return a.y!=b.y?a.y<b.y:a.idx<b.idx;
     32     }
     33 };
     34 
     35 int n,r;
     36 int ans=1;
     37 int counter=0;
     38 int head=0;
     39 int par[MAX_N];
     40 int cnt[MAX_N];
     41 Coor c[MAX_N];
     42 multiset<Coor> mst;
     43 
     44 inline bool cmp_x(const Coor &a,const Coor &b)
     45 {
     46     return a.x<b.x;
     47 }
     48 
     49 void init_union_find()
     50 {
     51     for(int i=0;i<n;i++)
     52     {
     53         par[i]=i;
     54     }
     55 }
     56 
     57 int find(int x)
     58 {
     59     return par[x]==x?x:par[x]=find(par[x]);
     60 }
     61 
     62 void unite(int x,int y)
     63 {
     64     int px=find(x);
     65     int py=find(y);
     66     if(px==py) return;
     67     par[px]=py;
     68 }
     69 
     70 void read()
     71 {
     72     cin>>n>>r;
     73     int a,b;
     74     for(int i=0;i<n;i++)
     75     {
     76         cin>>a>>b;
     77         c[i].x=a+b;
     78         c[i].y=a-b;
     79         c[i].idx=i;
     80     }
     81 }
     82 
     83 void solve()
     84 {
     85     init_union_find();
     86     sort(c,c+n,cmp_x);
     87     mst.insert(Coor(0,INF,0));
     88     mst.insert(Coor(0,-INF,0));
     89     mst.insert(c[head]);
     90     for(int i=1;i<n;i++)
     91     {
     92         while(c[i].x-c[head].x>r)
     93         {
     94             mst.erase(c[head]);
     95             head++;
     96         }
     97         multiset<Coor>::iterator it=mst.lower_bound(c[i]);
     98         Coor suc=*it;
     99         Coor pre=*--it;
    100         if(c[i].y-pre.y<=r) unite(pre.idx,c[i].idx);
    101         if(suc.y-c[i].y<=r) unite(suc.idx,c[i].idx);
    102         mst.insert(c[i]);
    103     }
    104     memset(cnt,0,sizeof(cnt));
    105     for(int i=0;i<n;i++)
    106     {
    107         int p=find(i);
    108         if(cnt[p]==0) counter++;
    109         cnt[p]++;
    110         ans=max(ans,cnt[p]);
    111     }
    112 }
    113 
    114 void print()
    115 {
    116     cout<<counter<<" "<<ans<<endl;
    117 }
    118 
    119 int main()
    120 {
    121     read();
    122     solve();
    123     print();
    124 }
  • 相关阅读:
    2019-2020-1 20175311 20175324 20175330 实验四 外设驱动程序设计
    2019-2020-1 20175311 《信息安全系统设计基础》第十一周学习总结
    2019-2020-1《信息安全系统设计》20175311 20175324 20175330 实验三实时系统
    【2019-2020-1】20175330 20175324 20175311 实验二 固件程序设计
    2018-2019-1 20175311 20175324 20175330 实验一 开发环境的熟悉
    2019-2020-1 20175311胡济栋 《信息安全系统设计基础》第五周学习总结教材学习
    恶意代码分析
    免杀进阶
    Android的安装
    免杀原理与实践
  • 原文地址:https://www.cnblogs.com/Leohh/p/7599009.html
Copyright © 2011-2022 走看看