zoukankan      html  css  js  c++  java
  • bzoj 1577: [Usaco2009 Feb]庙会捷运Fair Shuttle——小根堆+大根堆+贪心

    Description

    公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N。K(1<=K<=50000)群奶牛希望搭乘这辆公交车。第i群牛一共有Mi(1<=Mi<=N)只.

    他们希望从Si到Ei去。
    公交车只能座C(1<=C<=100)只奶牛。而且不走重复路线,请计算这辆车最多能满足多少奶牛听要求。
    注意:对于每一群奶牛,可以部分满足,也可以全部满足,也可以全部不满足。

    Input

    第1行: 三个整数: K,N,C。 由空格隔开。

    第2..K+1行:第i+1行,告诉你第i组奶牛的信息: S_i, E_i and M_i。由空格隔开。

    Output

    一行:可以在庙会乘坐捷运的牛的最大头数

    Sample Input

    8 15 3
    1 5 2
    13 14 1
    5 8 3
    8 14 2
    14 15 1
    9 12 1
    12 15 2
    4 6 1

    Sample Output

    10

    HINT

    捷运可以把2头奶牛从展台1送到展台5,3头奶牛从展台5到展台8,

    2头奶牛从展台8 到展台14,1头奶牛从展台9送到展台12,

    一头奶牛从展台13送到展台14, 一头奶牛从 14送到15。

    ——————————————————————————————

    这道题我们维护两个堆 按终点距离为键值 维护一个大根堆 一个小根堆

    我们每次到一个点 就把所有到这个点(作为终点)的奶牛扔出堆(大根堆小根堆的信息要互通)

    表示他们已经下车了 到一个点之后把所有在这个点上车的牛全部扔进堆 表示他们要上车辣QAQ

    如果这个时候车上的人太多了(会出事的2333) 我们就贪心地把终点最远的扔出堆

    这样就可以得到最优解了2333

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<queue>
    const int M=3e4+7;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int f[2*M],cnt,cost,k,n,c,ans;
    struct pos{
        int id,h,ed;
        bool operator <(const pos &x)const{return x.ed<ed;}
    };
    std::vector<pos>e[M];
    std::priority_queue<pos>q1;
    struct Q{
        int id,h,ed;
        bool operator <(const Q &x)const{return x.ed>ed;}
    };
    std::priority_queue<Q>q2;
    int main(){
        int v,x,y;
        k=read(); n=read(); c=read();
        for(int i=1;i<=k;i++) x=read(),y=read(),v=read(),e[x].push_back((pos){++cnt,v,y});
        for(int i=1;i<=n;i++){
            while(!q1.empty()){
                pos x=q1.top(); 
                if(x.ed>i) break;
                q1.pop();
                if(f[x.id]) continue;
                f[x.id]=1; cost-=x.h; ans+=x.h; 
            }
            int mx=e[i].size();
            for(int j=0;j<mx;j++){
                q1.push((pos){e[i][j].id,e[i][j].h,e[i][j].ed});
                q2.push((Q){e[i][j].id,e[i][j].h,e[i][j].ed});
                cost+=e[i][j].h;
            }
            while(cost>c){
                Q x=q2.top(); q2.pop();
                if(f[x.id]) continue;
                f[x.id]=1;
                if(cost-c>=x.h){cost-=x.h; continue;}
                int now=cost-c;
                cnt++;
                q1.push((pos){cnt,x.h-now,x.ed});
                q2.push((Q){cnt,x.h-now,x.ed});
                cost=c;
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    一个多列组合框
    数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历
    数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历
    图结构练习——BFS——从起始点到目标点的最短步数
    图结构练习——BFS——从起始点到目标点的最短步数
    广度优先搜索介绍
    广度优先搜索介绍
    数据结构实验之二叉树一:树的同构
    数据结构实验之二叉树一:树的同构
    对代码不满足,是任何真正有天才的程序员的根本特征。
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7575850.html
Copyright © 2011-2022 走看看