zoukankan      html  css  js  c++  java
  • bzoj 1604 [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(set+并查集)

     

    Description

    了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个“群”.每只奶牛在吃草的 时候有一个独一无二的位置坐标Xi,Yi(l≤Xi,Yi≤[1..10^9];Xi,Yi∈整数.当满足下列两个条件之一,两只奶牛i和j是属于同一个 群的:
      1.两只奶牛的曼哈顿距离不超过C(1≤C≤10^9),即lXi - xil+IYi - Yil≤C.
      2.两只奶牛有共同的邻居.即,存在一只奶牛k,使i与k,j与k均同属一个群.
        给出奶牛们的位置,请计算草原上有多少个牛群,以及最大的牛群里有多少奶牛

    Input

       第1行输入N和C,之后N行每行输入一只奶牛的坐标.

    Output

    仅一行,先输出牛群数,再输出最大牛群里的牛数,用空格隔开.

    Sample Input

    4 2
    1 1
    3 3
    2 2
    10 10

    * Line 1: A single line with a two space-separated integers: the
    number of cow neighborhoods and the size of the largest cow
    neighborhood.



    Sample Output

    2 3

    OUTPUT DETAILS:
    There are 2 neighborhoods, one formed by the first three cows and
    the other being the last cow. The largest neighborhood therefore
    has size 3.

    HINT

    Source

    【思路】

           Set+并查集

           曼哈顿距离分为以下情况

        X-x+Y-y -> (X+Y)-(x+y)

        X-x+y-Y -> (X-Y)-(x-y)  

        x-X+Y-y -> -( (X-Y)-(x-y) )  

        x-X+y-Y -> -( (X+Y)-(x+y) )

      这四种情况,我们可以发现,答案就是

        max( |(X+Y)-(x+y)|, |(X-Y)-(x-y)| )

      于是把每个点变为(x+y,x-y) 并将x从小到大排序

      维护一个队列使得front~i区间x坐标的差均小于c

      用set维护队列元素中的y,如果i在set中的前驱或后继与i的y之差小于c则合并集合。

    【代码】

     1 #include<set>
     2 #include<cstdio>
     3 #include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 typedef long long LL;
     8 const int N = 1e5+10;
     9 const int INF = 1e9+1e9+7;
    10 struct Node{
    11     int x,y;
    12     bool operator < (const Node& rhs) const{
    13         return x<rhs.x;
    14     }
    15 }a[N];
    16 int n,c,p[N],sum[N],ans,mx;
    17 multiset<Node> S;
    18 multiset<Node> ::iterator it;
    19 
    20 int ifind(int u) {
    21     return u==p[u]? u:p[u]=ifind(p[u]);
    22 }
    23 void unit(int x,int y) {
    24     x=ifind(x),y=ifind(y); if(x!=y) p[x]=y;
    25 }
    26 
    27 void read(int& x) {
    28     char c=getchar(); int f=1; x=0;
    29     while(!isdigit(c)){if(c=='-')f=-1; c=getchar();}
    30     while(isdigit(c)) x=x*10+c-'0',c=getchar();
    31     x*=f;
    32 }
    33 int main() {
    34     read(n),read(c);
    35     for(int i=1;i<=n;i++) p[i]=i;
    36     int x,y;
    37     for(int i=1;i<=n;i++) {
    38         read(x),read(y);
    39         a[i].x=x+y,a[i].y=x-y;
    40     }
    41     sort(a+1,a+n+1);
    42     S.insert((Node){INF,0}),S.insert((Node){-INF,0});
    43     int front=1;
    44     for(int i=1;i<=n;i++) {
    45         while(a[i].x-a[front].x>c) {
    46             S.erase(S.lower_bound((Node){a[front].y,front}));
    47             ++front;
    48         }
    49         it=S.lower_bound((Node){a[i].y,i});
    50         Node r=*it,l=*(--it);
    51         if((LL)r.x-(LL)a[i].y<=c) unit(r.y,i);
    52         if((LL)a[i].y-(LL)l.x<=c) unit(l.y,i);
    53         S.insert((Node){a[i].y,i});
    54     }
    55     for(int i=1;i<=n;i++) {
    56         sum[ifind(i)]++;
    57         if(sum[ifind(i)]==1) ans++;
    58     }
    59     for(int i=1;i<=n;i++) mx=max(mx,sum[i]);
    60     printf("%d %d",ans,mx);
    61     return 0;
    62 }
    View Code
  • 相关阅读:
    Java 实现常见内排序
    markdown基本语法
    HashMap (JDK1.8) 分析
    jQuery总结
    JS 数组 常用方法
    CSS样式 解决文字过长显示省略号问题
    Python中的 __name__属性的含义和作用
    http协议详细介绍
    Http和Https的区别
    爬虫——requests库使用方法
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5192127.html
Copyright © 2011-2022 走看看