题意:
租车公司有n个预约, 每个预约有时间和地点, 地点分布在二维整数坐标系上, 地点之间的行驶时间为两点间的曼哈顿距离
(|x1 - x2| + |y1 - y2|)。一辆车可以在运完一个乘客后运另一个乘客, 条件是此车要在预约开始前一分钟之前到达出发地, 问最少需要几辆车搞定所有预约。
给出一些预约的起始时间,出发地和目的地,问至少需要多少车可以满足所有的预约
对于任何一对预约,如果前一预约的结束时刻加上到达下一个预约的所需时间小于下一个预约
的起始时间,就在两个预约之间连一条边,题目就转化为求该图的最小路径覆盖
看到这个题的第一眼,我觉得可以用贪心区间解决W,但是由于测试数据比较特殊(第二位乘客的起始地点正好的第一位乘客的下车目的地),我也忽略了司机的缓冲时间(到达下一个乘客预约地点的时间)。可是我还是不放弃贪心区间解决这个问题(我要继续想,先放上代码)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int map[505][505];
int v2_link[505];
int v2_vis[505];
int sum,n;
struct node
{
int s,a,b,c,d,e;
}q[505];
bool dfs(int x)
{
int y;
for(y=0;y<n;y++)
{
if(!v2_vis[y]&&map[x][y])
{
v2_vis[y]=1;
if(v2_link[y]==-1||dfs(v2_link[y]))
{
v2_link[y]=x;
return true;
}
}
}
return false;
}
int hungary()
{
int i,sum=0;
memset(v2_link,-1,sizeof(v2_link));
for(i=0;i<n;i++)
{
memset(v2_vis,0,sizeof(v2_vis));
if(dfs(i))
sum++;
}
return sum;
}
bool add(int x,int y)
{
if(x==y)return 0;
int temp=q[x].e+abs(q[y].a-q[x].c)+abs(q[y].b-q[x].d);
if(temp<q[y].s)
return 1;
return 0;
}
int main()
{
int T,h,m,a,b,c,d,i,j;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d:%d",&h,&m);
q[i].s=h*60+m;
scanf("%d%d%d%d",&q[i].a,&q[i].b,&q[i].c,&q[i].d);
q[i].e=q[i].s+abs(q[i].c-q[i].a)+abs(q[i].d-q[i].b);
}
memset(map,0,sizeof(map));
for(i=0;i<n;i++)
for(j=0;j<n;j++)
map[i][j]=add(i,j);
printf("%d\n",n-hungary());
}
return 0;
}
贪心区间(错误 )
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
struct node
{
int s,e;
}q[505];
int cmp(node a,node b)
{
return a.s<b.s;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,i,a,b,c,d,e,f;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d:%d%d%d%d%d",&a,&b,&c,&d,&e,&f);
q[i].s=a*60+b;
q[i].e=q[i].s+abs(e-c)+abs(f-d);
}
sort(q,q+n,cmp);
int max=q[0].e;
int sum=n;
for(i=1;i<n;i++)
{
if(q[i].s>max)
{
sum--;
max=q[i].e;
}
else
{
if(q[i].e<max)
{
max=q[i].e;
}
}
}
printf("%d\n",sum);
}
return 0;
}