洛谷 P2906 [USACO08OPEN]牛的街区Cow Neighborhoods | Set+并查集

题目:

https://www.luogu.org/problemnew/show/P2906


题解:

垃圾水题

#include<cstdio>
#include<algorithm>
#include<set>
#define N 100005
typedef long long ll;
using namespace std;
struct node
{
    ll x,y,id;
    bool operator < (const node &a)const {return y<a.y || (y==a.y && id<a.id);}
}p[N];
multiset <node> s;
multiset <node> :: iterator it;
ll n,c,q[N],l,r=-1,fa[N],sz[N],ans,mx;
bool cmp(node a,node b) {return a.x<b.x || (a.x==b.x && a.y<b.y);}
ll find(ll x) {return fa[x]=fa[x]==x?x:find(fa[x]);}
void merge(ll i,ll j)
{
    ll x=find(i),y=find(j);
    if (x==y) return;
    if (sz[x]>sz[y]) swap(x,y);
    fa[x]=y,sz[y]+=sz[x];
}
int main()
{
    scanf("%lld%lld",&n,&c);
    for (ll i=1,x,y;i<=n;i++)
        scanf("%lld%lld",&x,&y),p[i].x=x+y,p[i].y=x-y,p[i].id=fa[i]=i,sz[i]=1;
    sort(p+1,p+1+n,cmp);
    for (ll i=1;i<=n;i++)
    {
        q[++r]=i;
        while (l<r && p[q[r]].x-p[q[l]].x>c) s.erase(p[q[l]]),l++;
        it=s.insert(p[i]);
        if (it!=s.begin())
            if ((p[i].y-(*(--it)).y<=c)) merge(p[i].id,((*it).id)),it++;
            else it++;
        if (++it!=s.end() && (*(it)).y-p[i].y<=c )
            merge(p[i].id,(*it).id); 
    }
    for (ll i=1;i<=n;i++) 
        if (find(i)==i) ans++,mx=max(mx,sz[i]);
    printf("%lld %lld\n",ans,mx);
    return 0;
}

 

posted @ 2018-02-01 16:46  MSPqwq  阅读(141)  评论(0编辑  收藏  举报