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 }
原文地址:https://www.cnblogs.com/yu-xing/p/10350913.html