http://poj.org/problem?id=3038
这个题我是在一个关于并查集的博客中找到的,结果我就觉得这个应该是个贪心,真想不出这个与并查集有什么鬼关系,看discuss里面也都是贪心,我是不懂大神的想法,最后,我点开链接才发现那是杭电的3038.。。我也是醉了,然后一早上就搞了这一道题。贪心还是不怎么会。
题意:就是一个牛搞了一个航空公司,想让这个航空公司可以在一天来回运送最多的客人。求最多可以运送多少客人。
思路:discuss里面有个大神说的很简单,也很有道理。
1.碰到人,上车。
2.超载,最远的乘客下车。
3.行驶到下一站。
就这三句话,解决了这个题,可我还是有点懵,感觉思路还是不是很清晰。
最后看到了一个人的博客, 才最终懂了。
#include <stdio.h>
#include <string.h>
#include <queue>
#include <stdlib.h> #define maxn 50005 using namespace std; int ans = ,c,exist[ maxn ]; struct note{
int x,y,c;
}to[ maxn ],ba[ maxn ]; int cmp(const void *a,const void *b) //排序
{
if((*(note *)a).x != (*(note * )b).x)
return (*(note *)a).x - (*(note * )b).x;
else
return (*(note *)a).y - (*(note * )b).y;
} void deal(note tmp[],int x)
{
priority_queue<int,vector<int>,greater<int> >small;
priority_queue<int,vector<int>,less<int> >most;
int people = ,i;
memset( exist , , sizeof( exist ) );
for( i = ; i < x ; i++ )
{
small.push(tmp[i].y);
most.push(tmp[i].y);
exist[tmp[i].y] += tmp[i].c;
while(tmp[i].x>=small.top()) //有人到达了目的地,下车。
{
people -= exist[ small.top() ];
exist[ small.top() ] = ;
small.pop();
}
people += tmp[ i ].c; //上车。
ans += tmp[ i ].c;
if(people >c) //是否超载。
{
int t = people-c;
ans -= t;
people = c;
while(t)
{
if( exist[ most.top() ] > t)
{
exist[ most.top() ] -= t;
t = ;
}
else
{
t -= exist[ most.top() ];
exist[ most.top() ] = ;
most.pop();
}
}
}
}
} int main()
{
//freopen("in.txt","r",stdin);
int k,m,s,w,p,t = ,e = ;
scanf("%d%d%d",&k,&m,&c);
while( k-- )
{
scanf("%d%d%d",&s,&w,&p);
if( s < w )
{
to[ t ].x = s;
to[ t ].y = w;
to[ t++ ].c = p;
}
else
{
ba[ e ].x = w;
ba[ e ].y = s;
ba[ e++ ].c = p;
}
}
qsort( to , t , sizeof( to[ ] ) , cmp );
deal( to , t );
qsort( ba , e , sizeof( ba[ ] ) , cmp );
deal( ba , e );
printf("%d\n",ans);
return ;
}