POJ 2010 (优先队列

用优先队列扫一次得到大于和小于中位数的总和的最小值,再扫一遍得到最优解

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<utility>
#include<vector>
#define INF 0x3fffffff
using namespace std;
typedef long long ll;
int N,C,F;
typedef pair<int,int> pii;
const int maxv=1e5+30;
pair<int,int> cow[maxv];////score,aid
ll low[maxv],upp[maxv];
bool cmp(pii a,pii b){
    return a.second<b.second;
}
int main(){
    freopen("in.txt","r",stdin);
    cin>>N>>C>>F;
    for(int i=0;i<C;i++) scanf("%d%d",&cow[i].first,&cow[i].second);
    sort(cow,cow+C);
    ll tol=0;
    priority_queue<int> Q1,Q2;
    ll half=N/2;
    for(int i=0;i<C;i++){
        low[i]=(Q1.size()==half?tol:INF);
        Q1.push(cow[i].second);
        tol+=cow[i].second;
        if(Q1.size()>half){
            tol-=Q1.top();
            Q1.pop();
        }
    }
    tol=0;
    for(int i=C-1;i>=0;i--){
        upp[i]=(Q2.size()==half?tol:INF);
        Q2.push(cow[i].second);
        tol+=cow[i].second;
        if(Q2.size()>half){
            tol-=Q2.top();
            Q2.pop();
        }
    }
    int ans=-1;
    for(int i=0;i<C;i++){
        if(low[i]+upp[i]+cow[i].second<=F)
            ans=cow[i].first;
    }
    cout<<ans<<endl;
    return 0;
}

 

posted @ 2015-05-01 16:23  PlusSeven  阅读(145)  评论(0编辑  收藏  举报