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 }