题目大意:
给你M个出租车请求,告诉你每个请求的出发时间s,起点坐标(x1,y1),终点坐标(x2,y2)。要你求出完成所有请求所需要的最少出租车辆数。(其中若一辆出租车完成请求u后,从u的终点赶到请求v的起点后的时间小于请求v的起始时间。那么这辆出租车还可以去完成请求v)。
思路分析:
将一个请求作为有向无环图的一个节点,若请求u完成后能够赶到请求v,那么在有向图u到v之间连有向边。然后求这个有向图的最小路径覆盖。注意是有向的!!!
最小路径覆盖数=节点数M-最大匹配数
感想:
分别用邻接矩阵和邻接表实现。发现我用邻接表写的比邻接矩阵还慢!!!。。。。受挫。。。。。。
CODE(1):邻接矩阵
/*最小路径覆盖*/
/*有向无环图*/
/*最小路径覆盖 = |M| - 最大匹配数*/
/*邻接矩阵实现*/
/*AC代码:125ms*/
#include <iostream>
#include <cmath>
#include <string>
#define MAXN 505
using namespace std;
bool map[MAXN][MAXN];
bool flag[MAXN];
int result[MAXN];
struct px
{
int x1,y1,x2,y2,s,e;
};
struct px P[MAXN];
int M;
int Find(int a)
{
int i;
for(i=1;i<=M;i++)
{
if(map[a][i]&&!flag[i])
{
flag[i]=true;
if(result[i]==0||Find(result[i]))
{
result[i]=a;
return 1;
}
}
}
return 0;
}
int MaxMatch()
{
int ans=0,i;
memset(result,0,sizeof(result));//忘记初始WA好几次!!!
for(i=1;i<=M;i++)
{
memset(flag,false,sizeof(flag));
ans+=Find(i);
}
return ans;
}
void Build()
{
memset(map,false,sizeof(map));
int i,j,k;
for(i=1;i<=M;i++)
{
for(j=M;j>i;j--)
{
if((P[i].e+abs(P[j].x1-P[i].x2)+abs(P[j].y1-P[i].y2))<P[j].s)
map[i][j]=true;
if(P[i].e>=P[j].s)
break;
}
}
}
int main()
{
int T,i,j,h,m;
//char ss[10];
scanf("%d",&T);
while(T--)
{
scanf("%d",&M);
for(i=1;i<=M;i++)
{
//scanf("%s",ss);
//sscanf(ss,"%d%*[:]%d",&h,&m);
scanf("%d:%d",&h,&m);
scanf("%d%d%d%d",&P[i].x1,&P[i].y1,&P[i].x2,&P[i].y2);
P[i].s=h*60+m;
P[i].e=P[i].s+abs(P[i].x1-P[i].x2)+abs(P[i].y1-P[i].y2);
}
Build();
printf("%d\n",M-MaxMatch());
}
return 0;
}
CODE(2):邻接表实现
/*最小路径覆盖*/
/*有向无环图*/
/*最小路径覆盖 = |M| - 最大匹配数*/
/*用邻接表*/
/*AC代码:235ms*/
#include <iostream>
#include <cmath>
#include <string>
#define MAXN 505
using namespace std;
bool flag[MAXN];
int result[MAXN];
int link[MAXN][MAXN];
struct px
{
int x1,y1,x2,y2,s,e;
};
struct px P[MAXN];
int M;
int Find(int pos)
{
int i;
for(i=1;i<=link[pos][0];i++)
{
int t=link[pos][i];
if(!flag[t])//注意
{
flag[t]=true;
if(result[t]==0||Find(result[t]))
{
result[t]=pos;
return 1;
}
}
}
return 0;
}
int MaxMatch()
{
int ans=0,i;
memset(result,0,sizeof(result));//忘记初始WA好几次!!!
for(i=1;i<=M;i++)
{
if(link[i][0])
{
memset(flag,false,sizeof(flag));
ans+=Find(i);
}
}
return ans;
}
void Build()
{
int i,j,k;
memset(link,0,sizeof(link));
for(i=1;i<=M;i++)
{
for(k=0,j=M;j>i;j--)
{
if((P[i].e+abs(P[j].x1-P[i].x2)+abs(P[j].y1-P[i].y2))<P[j].s)
link[i][++k]=j;
if(P[i].e>=P[j].s)
break;
}
link[i][0]=k;
}
}
int main()
{
int T,i,j,h,m;
scanf("%d",&T);
while(T--)
{
scanf("%d",&M);
for(i=1;i<=M;i++)
{
scanf("%d:%d",&h,&m);
scanf("%d%d%d%d",&P[i].x1,&P[i].y1,&P[i].x2,&P[i].y2);
P[i].s=h*60+m;
P[i].e=P[i].s+abs(P[i].x1-P[i].x2)+abs(P[i].y1-P[i].y2);
}
Build();
printf("%d\n",M-MaxMatch());
}
return 0;
}