zoukankan      html  css  js  c++  java
  • BZOJ 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居


    题目


    1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居

    Time Limit: 5 Sec  Memory Limit: 64 MB

    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行输入NC,之后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.

    题解


    这题很明显就是再考并查集!【真的吗,你看下数据范围!】关于曼哈顿距离的技巧,将每个点变成(x+y,x-y)这样两个点之间的曼哈顿距离就是|x1-x2|+|y1-y2|,这样就可以维护一个平衡树,根据前驱和后继上面的节点来维护并查集求得答案了!


    代码


    /*Author:WNJXYK*/
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<queue>
    #include<set>
    #include<map>
    using namespace std;
    
    #define LL long long
    #define Inf 2147483647
    #define InfL 10000000000LL
    
    inline void swap(int &x,int &y){int tmp=x;x=y;y=tmp;}
    inline void swap(LL &x,LL &y){LL tmp=x;x=y;y=tmp;}
    inline int remin(int a,int b){if (a<b) return a;return b;}
    inline int remax(int a,int b){if (a>b) return a;return b;}
    inline LL remin(LL a,LL b){if (a<b) return a;return b;}
    inline LL remax(LL a,LL b){if (a>b) return a;return b;}
    
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,c,ans,mx;
    int fa[100005],tot[100005];
    struct data{LL x,y;int id;}a[100005];
    multiset <data> b;
    set <data>::iterator it;
    inline bool operator<(data a,data b){
        return a.y<b.y;
    }
    inline bool cmpx(data a,data b){
        return a.x<b.x;
    }
    int find(int x){
        return x==fa[x]?x:fa[x]=find(fa[x]);
    }
    inline void un(int x,int y){
        int p=find(x),q=find(y);
        if(p!=q){
            fa[p]=q;
            ans--;
        }
    }
    void solve(){
        b.insert((data){0,InfL,0});b.insert((data){0,-InfL,0});   
        int now=1;b.insert(a[1]);
        for(int i=2;i<=n;i++){
            while(a[i].x-a[now].x>c){
                b.erase(b.find(a[now]));
                now++;
            }
            it=b.lower_bound(a[i]);
            data r=*it,l=*--it;
            if(a[i].y-l.y<=c)
                un(a[i].id,l.id);
            if(r.y-a[i].y<=c)
                un(a[i].id,r.id);
            b.insert(a[i]);
        }
    }
    int main(){
        n=read();c=read();ans=n;
        for(int i=1;i<=n;i++)fa[i]=i;
        for(int i=1;i<=n;i++){
            int t1=read(),t2=read();
            a[i].x=t1+t2,a[i].y=t1-t2;a[i].id=i;
        }
        sort(a+1,a+n+1,cmpx);
        solve();
        for(int i=1;i<=n;i++)
            tot[find(i)]++;
        for(int i=1;i<=n;i++)
            mx=max(mx,tot[i]);
        printf("%d %d
    ",ans,mx);
        return 0;
    }
    




  • 相关阅读:
    Mac系统下安装和卸载HomeBrew的方法
    .NET笔试题集(五)
    .NET笔试题集(四)
    .NET笔试题集(二)
    .NET笔试题集(三)
    .NET笔试题集(一)
    C# 文件操作方法
    MD5 加密的两种方法
    jquery 元素选择器集合
    Jquery元素追加和删除
  • 原文地址:https://www.cnblogs.com/WNJXYK/p/4063928.html
Copyright © 2011-2022 走看看