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

来源:互联网 发布:serge lang知乎 编辑:程序博客网 时间:2024/05/01 22:40

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

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 595  Solved: 263
[Submit][Status][Discuss]

Description

与很多奶牛一样,Farmer John那群养尊处优的奶牛们对食物越来越挑剔,随便拿堆草就能打发她们午饭的日子自然是一去不返了。现在,Farmer John不得不去牧草专供商那里购买大量美味多汁的牧草,来满足他那N(1 <= N <= 100,000)头挑剔的奶牛。 所有奶牛都对FJ提出了她对牧草的要求:第i头奶牛要求她的食物每份的价钱不低于A_i(1 <= A_i <= 1,000,000,000),并且鲜嫩程度不能低于B_i(1 <= B_i <= 1,000,000,000)。商店里供应M(1 <= M <= 100,000)种不同的牧草,第i 种牧草的定价为C_i(1 <= C_i <= 1,000,000,000),鲜嫩程度为D_i (1 <= D_i <= 1,000,000,000)。 为了显示她们的与众不同,每头奶牛都要求她的食物是独一无二的,也就是说,没有哪两头奶牛会选择同一种食物。 Farmer John想知道,为了让所有奶牛满意,他最少得在购买食物上花多少钱。

Input

* 第1行: 2个用空格隔开的整数:N 和 M

* 第2..N+1行: 第i+1行包含2个用空格隔开的整数:A_i、B_i * 第N+2..N+M+1行: 第j+N+1行包含2个用空格隔开的整数:C_i、D_i

Output

* 第1行: 输出1个整数,表示使所有奶牛满意的最小花费。如果无论如何都无法 满足所有奶牛的需求,输出-1

Sample Input

4 7
1 1
2 3
1 4
4 2
3 2
2 1
4 3
5 2
5 4
2 6
4 4

Sample Output

12

输出说明:

给奶牛1吃价钱为2的2号牧草,奶牛2吃价钱为4的3号牧草,奶牛3分到价钱
为2的6号牧草,奶牛4选择价钱为4的7号牧草,这种分配方案的总花费是12,为
所有方案中花费最少的。



平衡树+贪心。。bzoj里面不能用srand(time(0)).........

首先将所有数据按钱为第一关键字新鲜度为第二关键字排序

从小到大枚举牧草,把符合钱的牛扔进平衡树,显然我们需要找到平衡树内满足条件且第二关键字最大的

#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<string>#include<queue>#include<stack>#include<vector>#include<cstdlib>#include<map>#include<cmath>#include<ctime>using namespace std;const int maxn = 1e5 + 10;struct G{int p,v;bool operator < (const G &b) const{if (p < b.p) return 1;if (p > b.p) return 0;return v < b.v;}}cow[maxn],gra[maxn];class data{private:struct Node{int pri,val;Node *ch[2];}*root,*tot,pool[maxn];void rotate(Node *&x,int d){Node *y = x->ch[d];x->ch[d] = y->ch[d^1];y->ch[d^1] = x;x = y;}void Insert(Node *&x,int pri,int val){if (x == NULL){x = tot++;x->pri = pri; x->val = val;x->ch[0] = NULL; x->ch[1] = NULL;return;}int d = x->val > val ? 0:1;Insert(x->ch[d],pri,val);if (x->ch[d]->pri > x->pri) rotate(x,d);}void Remove(Node *&x,int val){int d = x->val > val ? 0:1;if (x->val == val){if (x->ch[0] == NULL && x->ch[1] == NULL){x = NULL;return;}if (x->ch[0] == NULL && x->ch[1] != NULL){x = x->ch[1];return;}if (x->ch[1] == NULL && x->ch[0] != NULL){x = x->ch[0];return;}int d1 = x->ch[0]->pri > x->ch[1]->pri?0:1;rotate(x,d1);Remove(x->ch[d1^1],val); return;}Remove(x->ch[d],val); }int Lower_bound(Node *x,int val){int ret = -1;while (x != NULL){int d = x->val > val ? 0:1;if (x->val <= val) ret = max(ret,x->val);x = x->ch[d];}return ret;}public:data(){root = NULL; tot = pool;}void Ins(int val){Insert(root,rand(),val);}void Rem(int val){Remove(root,val);}int L_b(int val){return Lower_bound(root,val);}};int n,m,i,j;long long ans = 0;int main(){#ifndef ONLINE_JUDGE#ifndef YZY  freopen(".in","r",stdin);  freopen(".out","w",stdout);#else  freopen("yzy.txt","r",stdin);#endif#endif//srand(time(0));static data tree;//tree.Ins(2E9);cin >> n >> m;for (i = 1; i <= n; i++) scanf("%d%d",&cow[i].p,&cow[i].v);for (i = 1; i <= m; i++) scanf("%d%d",&gra[i].p,&gra[i].v);sort (cow + 1,cow + n + 1);sort (gra + 1,gra + m + 1);j = 1; int sat = 0;for (i = 1; i <= m; i++){while (j <= n && cow[j].p <= gra[i].p)   tree.Ins(cow[j++].v);int val = tree.L_b(gra[i].v);if (val != -1){ans += 1LL*gra[i].p;tree.Rem(val);++sat;if (sat == n){cout << ans;return 0;}}}cout << -1;return 0;}


0 0
原创粉丝点击