Problem : Taxi Cab Scheme
Description : 出租车接客,每个订单都有出行时间,出发地址,目的地址。一辆出租车在保证乘客能在规定的出发时间之前出发,那么这辆出租车就能接下多单。现在问你最少要多少台出租车才能完成所有的订单。
Solution : 二分图的最小路径覆盖。这是我的第一道最小路径覆盖。主要是学习了建图和最小路径覆盖的基本思想和意义,我分别讲下建图和最小路径覆盖的思想。最小路径覆盖的思想–用最少的路径来覆盖所有的顶点,且路径不能有交点。如果你能理解二分图的最小路径覆盖=图中节点数−最大匹配数,那么你就能很好地理解这个思想,建图的时候就能把握关键。建图–订单只能由唯一的一辆出租车完成,且所有的订单都要完成,看到这里我们就有种感觉要以订单作为点了。那么点和点之间的边又是怎么构建的呢,如果两个订单能用一辆出租车完成,那么就连边,判断依据是该订单完成的时间加上车赶到下一个订单的出发地址的时间是否小于下一个订单出发地址的出发时间。那么一条路径就代表着一辆出租车,如果一个点没有边,那么这条路径的长度就是0,也就是说,我们只能再用一辆新的出租车来完成这个订单了。
Code(C++) :
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <vector>
#define ABS(a) ((a)>0? (a):(-(a)))
using namespace std;
const int F=500+25;
typedef struct tagNode{
int h,s;
int a,b,c,d;
tagNode(){}
tagNode(int H,int S,int A,int B,int C,int D):
h(H),s(S),a(A),b(B),c(C),d(D){}
}Node;
int n;
vector<int> edge[F];
bool used[F];
int belong[F];
Node line[F];
bool dfs(int s)
{
for(int i=0;i<edge[s].size();i++){
int end=edge[s].at(i);
if(used[end])
continue;
used[end]=true;
if(belong[end]==-1||dfs(belong[end])){
belong[end]=s;
return true;
}
}
return false;
}
int main()
{
//freopen("in.data","r",stdin);
int N;
cin>>N;
while(N--){
for(int i=0;i<F;i++)
edge[i].clear();
memset(belong,-1,sizeof(belong));
cin>>n;
int h,s,a,b,c,d;
for(int i=1;i<=n;i++)
scanf("%d:%d%d%d%d%d",&h,&s,&a,&b,&c,&d),
line[i]=Node(h,s,a,b,c,d);
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
if(60*line[i].h+line[i].s+ABS(line[i].a-line[i].c)+ABS(line[i].b-line[i].d)+ABS(line[i].c-line[j].a)+ABS(line[i].d-line[j].b)<60*line[j].h+line[j].s)
edge[i].push_back(j);
int sum=0;
for(int i=1;i<=n;i++){
memset(used,false,sizeof(used));
if(dfs(i))
++sum;
}
printf("%d\n",n-sum);
}
return 0;
}