admin 管理员组

文章数量: 887007

POJ 3622 Gourmet Grazers (数据结构)

Description

Like so many others, the cows have developed very haughty tastes and will no longer graze on just any grass. Instead, Farmer John must purchase gourmet organic grass at the Green Grass Grocers store for each of his N (1 ≤ N ≤ 100,000) cows.

Each cow i demands grass of price at least Ai (1 ≤ Ai ≤ 1,000,000,000) and with a greenness score at least Bi (1 ≤ Bi ≤ 1,000,000,000). The GGG store has M (1 ≤ M ≤ 100,000) different types of grass available, each with a price Ci (1 ≤ Ci ≤ 1,000,000,000) and a greenness score of Di (1 ≤ Di ≤ 1,000,000,000). Of course, no cow would sacrifice her individuality, so no two cows can have the same kind of grass.

Help Farmer John satisfy the cows’ expensive gourmet tastes while spending as little money as is necessary.

Input

  • Line 1: Two space-separated integers: N and M.
  • Lines 2..N+1: Line i+1 contains two space-separated integers: Ai and Bi
  • Lines N+2..N+M+1: Line i+N+1 contains two space-separated integers: Ci and Di

Output

  • Line 1: A single integer which is the minimum cost to satisfy all the cows. If that is not possible, output -1.

题意

有 N 头牛与 M 种草,给定第 i 头要吃的草的最低价格为 Ai ,草的最低质量为 Bi 。M 种草每种草的价格为 Ci ,质量为 Di 。同时每头牛吃的草的种类要不同,问使得每头牛都吃到满足条件的草所需要花费的最少价格?

分析

用点数据结构来模拟实现即可。

通用做法为:二维数组记录牛要吃的草的要求和草的规格, ci, si 。均按照草的质量从大到小排序。通过枚举排序后数组 ci ,对于每个 ci , 将数组 s 中满足 ci.y<=si.y 加入可以实现 O(logn) 插入,查找,删除的数据结构中(个人选择了使用 set),HINT: 由于数组已经排序,查找数组 s 中满足条件的数只需线性扫描即可,具体请看代码来理解。

之后,对上述枚举的 ci ,在集合中查找最小的满足大于等于 ci.x 的数。 记录对答案的贡献,并从集合中删除该数。

注意: 使用 STL 的 lower_bound(start, end, value) 与使用 set 中的函数 set::lower_bound(value) 。两者的效率是不同的。set 中的 lower_bound(value) 函数可以做到 O(logn) 的二分查找,但使用 lower_bound(start, end, value) 只能用迭代器的线性扫描。复杂度完全不同。

代码

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<set>
using namespace std;
const int N = 100000 + 10;
const int M = 100000 + 10;
int n, m;
long long ans = 0;
struct Node {int x, y;
}c[N], s[M];
bool cmp(Node a, Node b) {if(a.y == b.y)  return a.x < b.x;return a.y > b.y;
}
multiset<pair<int, int> > st;
multiset<pair<int, int> >::iterator it;
bool operator<(pair<int, int> a, pair<int,int> b) {return a.first < b.first;
}
int main()
{for(;scanf("%d %d",&n,&m)!=EOF;){ans = 0;st.clear();for(int i=0;i<n;i++)scanf("%d %d",&c[i].x, &c[i].y);for(int i=0;i<m;i++)scanf("%d %d",&s[i].x, &s[i].y);sort(c, c+n, cmp);sort(s, s+m, cmp);int idx = 0;for(int i=0;i<n;i++){while(idx < m && s[idx].y >= c[i].y){st.insert(make_pair(s[idx].x, idx));idx++;}it = st.lower_bound(make_pair(c[i].x, 0));if(it == st.end()) {ans = -1;   break;}ans += it->first;st.erase(it);}printf("%I64d\n",ans);}
}

本文标签: POJ 3622 Gourmet Grazers (数据结构)