hdu 4864

来源:互联网 发布:淘宝客在哪里进去入口 编辑:程序博客网 时间:2024/05/22 11:58

100000的数据量,如果用二分图匹配的话边最多有10^10条....Hopcroft-Karp都过不了

那就只能贪心了.

首先发现y很小,才100,而且按照钱的计算方法,x起决定作用

所以可以把tasks按x,y排序,x大的task优先完成

然后就是如何贪心匹配了:

对于task(tx,ty),首先肯定只能找machine(mx>=tx,my>=ty),如果只有一个的话那就直接选(因为每个machin只能用一次,而现在的tast是钱最多的)

如果有多个,见下图:


我们正在为三角task选machin,可选的有三个1,2,3,按常理要么我们选x最接近的3,要么选y最接近的1

如果选3的话:那么在之后的选择中会出现左边那个圆圈(x比较小,y比较大),由于你把3选走了,导致最终结果少匹配了一个,所以是错的

如果选1的话:可以看到右下方有个圆圈...(x比较大,y比较小),你又抢了它的1>_<

但是...由于你是排好序x大的先选,所以右下那个圆圈肯定已经选完了,所以选1是正确的


结论就是:在mx>tx的machine中选一个y值最小的匹配就行。


#include <iostream>#include <cstdio>#include <cstring>#include <set>#include <algorithm>using namespace std;typedef long long LL;const int maxn=100000+100;int N,M;struct Node{    int x,y;    bool operator<(const Node &a)const    {        if(x==a.x)            return y>a.y;        else return x>a.x;    }};multiset<int> mc[110];Node ts[maxn];int main(){    freopen("in.txt","r",stdin);    LL  res,cnt;    while(~scanf("%d%d",&N,&M))    {        for(int i=0;i<=100;i++)            mc[i].clear();        cnt=res=0;        Node tn;        for(int i=0;i<N;i++)        {            scanf("%d%d",&tn.x,&tn.y);            mc[tn.y].insert(tn.x);        }        for(int i=0;i<M;i++)        {            scanf("%d%d",&tn.x,&tn.y);            ts[i]=tn;        }        sort(ts,ts+M);        for(int i=0;i<M;i++)        {            for(int y=ts[i].y;y<=100;y++)            {                set<int>::iterator iter= mc[y].lower_bound(ts[i].x);                if(iter!=mc[y].end())                {                    res+=ts[i].x*500+ts[i].y*2;                    cnt++;            //        cout<<*iter<<" "<<y<<endl;            //        cout<<ts[i].x<<" "<<ts[i].y<<endl<<endl;                    mc[y].erase(iter);                    break;                }            }        }        cout<<cnt<<" "<<res<<endl;    }    return 0;}


0 0
原创粉丝点击