• POJ3038 Flying Right


     1 //思路:贪心+堆
     2 //不太好写啊 (抄的题解...)
     3 #include <stdio.h>
     4 #include <string.h>
     5 #include <queue>
     6 #include <stdlib.h>
     7 #include <algorithm>
     8 using namespace std;
     9 const int maxk=50005;
    10 using namespace std;
    11 int ans,k,n,c,cnt1,cnt2,exist[maxk];
    12 struct node{
    13     int from,to,num;
    14 }to[maxk],ba[maxk];//to--去程 ba--返程 
    15 inline bool cmp(const node &a,const node &b){
    16     return a.from<b.from;//按出发点排序 
    17 }
    18 void solve(node tmp[],int cnt){
    19     int people=0;//模拟 当前飞机人数 
    20     memset(exist,0,sizeof(exist));//exist--每站下飞机人数 
    21     priority_queue<int,vector<int>,greater<int> >small;//目的地最近的 
    22     priority_queue<int,vector<int>,less<int> >most;//目的地最远的 
    23     for(int i=1;i<=cnt;++i){
    24         small.push(tmp[i].to); //放进堆里 
    25         most.push(tmp[i].to);
    26         exist[tmp[i].to]+=tmp[i].num;//增加该站(当前旅客的目的地)下飞机人数 
    27         while(tmp[i].from>=small.top()){//当前站大于等于飞机乘客最近目的地 说明有人到达了目的地,需要下飞机
    28             people-=exist[small.top()];//飞机上人数减少 
    29             exist[small.top()]=0;//到达目的地后那一站的所有旅客都下飞机 
    30             small.pop();
    31         } 
    32         people+=tmp[i].num;//飞机人数加上这一站旅客 
    33         ans+=tmp[i].num;//答案也增加这一站旅客数 
    34         if(people>c){//若飞机超载 
    35             int d=people-c;//超载人数 
    36             ans-=d;//更新答案 
    37             people=c;//飞机保留最大载客数 
    38             while(d){//把飞机上原有目的地最远的旅客踢下 直至不超载 
    39                 if(exist[most.top()]>d){//若最远目的地站下飞机的旅客多于超载数 
    40                     exist[most.top()]-=d;//只把到那一站的旅客踢去一部分 
    41                     d=0;
    42                 }
    43                 else{
    44                     d-=exist[most.top()];//否则按目的地远近依次踢旅客 直至不超载 
    45                     exist[most.top()]=0;
    46                     most.pop();
    47                 }
    48             }
    49         }
    50     }
    51 }
    52 int main()
    53 {
    54     scanf("%d%d%d",&k,&n,&c);
    55     for(int i=1,x,y,z;i<=k;++i){
    56         scanf("%d%d%d",&x,&y,&z);
    57         if(x<y){//去程 
    58             to[++cnt1].from=x;to[cnt1].to=y;to[cnt1].num=z;
    59         }
    60         else{//返程 交换出发点和目的地 便于处理 
    61             ba[++cnt2].from=y;ba[cnt2].to=x;ba[cnt2].num=z;
    62         }
    63     }
    64     sort(to+1,to+1+cnt1,cmp);//分别按出发点排序后处理 
    65     sort(ba+1,ba+1+cnt2,cmp);
    66     solve(to,cnt1);
    67     solve(ba,cnt2);
    68     printf("%d
    ",ans);
    69     return 0;
    70 }
  • 相关阅读:
    求菲波那契数列的第n个数
    一个球,初始高度100,每次落下回弹一半高度,求第n次落下球走的距离
    MySQL优化
    linux常用命令2
    win7安装ANT
    win7配置java环境变量
    kvm虚拟机磁盘文件读取小结
    kvm linux虚拟机在线扩展磁盘
    binlog2sql
    linux上 查看mysql的binglog日志
  • 原文地址:https://www.cnblogs.com/yu-xing/p/10350913.html
Copyright © 2020-2023  润新知