[USACO 2009 Feb Gold] Fair Shuttle (贪心+优先队列)
题目大意:有N个站点的轻轨站,有一个容量为C的列车起点在1号站点,终点在N号站点,有K组牛群,每组数量为Mi(1≤Mi≤N),行程起点和终点分别为Si和Ei(1≤Si<Ei≤N)。计算最多有多少头牛可以搭乘轻轨。
一道经典的贪心题目,每当一头牛上车的时候,如果超载,我们就优先踢出去行程终点比较远的那部分牛
而 踢出哪些行程终点较远的牛 以及 哪些在车上的牛在这站到达了终点,都可以用优先队列来维护,复杂度约为
贴上代码:
1 #include <cstdio> 2 #include <algorithm> 3 #include <queue> 4 #include <cstring> 5 #define N 50005 6 #define ll long long 7 using namespace std; 8 9 int k,n,c,ans; 10 int sum[N]; 11 struct COW{ 12 int x,y,w; 13 }cow[N]; 14 int cmp(COW s1,COW s2) {return s1.x<s2.x;} 15 struct node1{ 16 int id; 17 friend bool operator<(const node1 &s1,const node1 &s2) 18 {return cow[s1.id].y > cow[s2.id].y;} 19 }; 20 node1 ins1(int idd){node1 w;w.id=idd;return w;} 21 struct node2{ 22 int id; 23 friend bool operator<(const node2 &s1,const node2 &s2) 24 {return cow[s1.id].y < cow[s2.id].y;} 25 }; 26 node2 ins2(int idd){node2 w;w.id=idd;return w;} 27 int solve() 28 { 29 sort(cow+1,cow+k+1,cmp); 30 priority_queue<node1>q1; 31 priority_queue<node2>q2; 32 int j=1,cnt=0; 33 for(int i=1;i<=n;i++) 34 { 35 while(!q1.empty()) 36 { 37 node1 p=q1.top(); 38 if(cow[p.id].y==i) 39 { 40 q1.pop(); 41 ans+=sum[p.id]; 42 cnt-=sum[p.id]; 43 sum[p.id]=0; 44 }else{ 45 break; 46 } 47 } 48 while(cow[j].x==i) 49 { 50 q1.push(ins1(j)); 51 q2.push(ins2(j)); 52 cnt+=cow[j].w; 53 sum[j]=cow[j].w; 54 j++; 55 } 56 while(cnt>c) 57 { 58 node2 p=q2.top(); 59 if(cnt-sum[p.id]>c) 60 { 61 q2.pop(); 62 cnt-=sum[p.id]; 63 sum[p.id]=0; 64 }else{ 65 sum[p.id]-=(cnt-c); 66 cnt=c; 67 } 68 } 69 } 70 return ans; 71 } 72 73 int main() 74 { 75 scanf("%d%d%d",&k,&n,&c); 76 for(int i=1;i<=k;i++) scanf("%d%d%d",&cow[i].x,&cow[i].y,&cow[i].w); 77 printf("%d",solve()); 78 return 0; 79 }