BZOJ-1577: [Usaco2009 Feb]庙会捷运Fair Shuttle

[文章目录]

Description

告诉你一辆能乘c个人的车,从1站点走到n站点。给出每个站点上车人数,以及他们的目的地。询问最多满足的人数。n<=20000,c<=100

看出来是贪心了。到一站先将车上达到目的地的人扔下去(233),尽量上人,如果不能上人,比较目的地。如果车上人的目的地远于将要上车的人,将车上的人赶下车。

然后实现方法感觉好tm恶心啊。。。码力不行啊。

先写了个堆,然后,在删除的时候巨恶心。

然后,听某人说是线段树???考虑了一下,从远到近循环车上的目的地修改的话感觉also好恶心。

删除???插入???循环遍历???排好序???
想到了set。
写的时候发现一个问题,不能直接改变set的元素。说是那是read_only。那么就删了重加。
Tips:
从后向前遍历set中的元素的时候,如果操作带有删除,感觉最好每次将iterator赋值,鬼知道set删除了之后的iterator还是不是原来的iterator。
这对码力的考验。。。略微感人。

#include <set>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,m,ans,sum,c;

struct node {int tar,num;};

bool operator < (node x,node y){return x.tar==y.tar ? x.num<y.num : x.tar<y.tar;}

set <node> s;
set <node>::iterator it;

vector<node>v[21000];

int main()
{
    scanf("%d%d%d",&m,&n,&c);
    int x,y,z;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        v[x].push_back((node){y,z});
    }
    for(int i=1;i<=n;i++)
    {
        it=s.lower_bound((node){i,-1});
        if(it!=s.end()&&it->tar==i)
        {
            ans+=it->num;
            sum-=it->num;
            s.erase(it);
        }
        for(int j=0;j<v[i].size();j++)
        {
            x=v[i][j].tar,y=v[i][j].num;
            if(sum<c)
            {
                int tmp=min(c-sum,y);
                it=s.lower_bound((node){x,-1});
                if(it!=s.end()&&it->tar==x)
                {
                    int yy=it->num;
                    s.erase(it);
                    s.insert((node){x,yy+tmp});
                }
                else s.insert((node){x,tmp});
                y-=tmp; sum+=tmp;
            }
            int cc=y;
            while(y)
            {
                it=s.end();
                if(it==s.begin()) break;
                it--; if(it->tar<=x) break;
                int tmp=min(it->num,y); y-=tmp;
                int xx=it->tar,yy=it->num-tmp;
                s.erase(it);
                if(yy) s.insert((node){xx,yy});
            }
            it=s.lower_bound((node){x,-1});
            if(it!=s.end()&&it->tar==x)
            {
                int yy=it->num+cc-y;
                s.erase(it);
                s.insert((node){x,yy});
            }
            else s.insert((node){x,cc-y});
        }
    }
    printf("%d\n",ans);
    return 0;
}

发表评论

邮箱地址不会被公开。 必填项已用*标注