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

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;
}


你可能感兴趣的:(1691: [Usaco2007 Dec]挑剔的美食家)