【BZOJ】1691: [Usaco2007 Dec]挑剔的美食家

【算法】扫描线+平衡树(set)

【题解】很明显的二维偏序数点,排序后扫描线,现加点后查询答案。

则问题转化为一维偏序,显然贪心找第一个比当前大的最优,所以用平衡树维护。

记得开multiset!!!

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<set>
#include<cctype>
using namespace std;
const int maxn=100010;
int n,m,tot;
long long ans=0;
struct cyc{int x,y,p;}b[maxn*2];
multiset<int>s;
multiset<int>::iterator it;//!!!
int read()
{
    char c;int s=0,t=1;
    while(!isdigit(c=getchar()))if(c=='-')t=-1;
    do{s=s*10+c-'0';}while(isdigit(c=getchar()));
    return s*t;
}
bool cmp(cyc a,cyc b){return a.y>b.y||(a.y==b.y&&a.p>b.p);}
int main(){
    n=read();m=read();
    tot=0;
    for(int i=1;i<=n;i++){//mat
        int u=read(),v=read();
        b[++tot]=(cyc){u,v,0};
    }
    for(int i=1;i<=m;i++){//point
        int u=read(),v=read();
        b[++tot]=(cyc){u,v,1};
    }
    sort(b+1,b+tot+1,cmp);
    for(int i=1;i<=tot;i++){
        if(b[i].p){
            s.insert(b[i].x);
        }
        else{
            it=s.lower_bound(b[i].x);
            if(it==s.end()){ans=-1;break;}
            ans+=*it;
            s.erase(it);
        }
    }
    printf("%lld",ans);
    return 0;
}
View Code

 

posted @ 2017-09-08 16:51  ONION_CYC  阅读(199)  评论(0编辑  收藏  举报