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\n",ans);
69 return 0;
70 }