标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1350
2 2 08:00 10 11 9 16 08:07 9 16 10 11 2 08:00 10 11 9 16 08:06 9 16 10 11
1 2
按照上述所给的数据及要求,输出最少所需要的司机数量。
解题思路:开始看到这道题目第一想法就是贪心,直接拿到达目标位置时间和下一个人的起始时间比较。但是做下去发现不能够得到最少的司机数量。这题我们应该采用二分匹配的最少边覆盖,最小路径覆盖=|n|-最大匹配数(n为定点数)
具体实现:将每一个人的坐标看成一个点。如果第一位司机接到a顾客后接到b,就将a,b连成一条有向边。并且要最少的司机覆盖所有点。完美的转化~~~
特别注意:
1、送乘客的时间为曼哈距离,公式为 |a - c| + |b - d|
2、每换乘一次需要间隔一分钟,所以不要忘记加1
详见代码。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct node
{
int stime,etime,sx,sy,ex,ey;
} p[510];
int Map[510][510];
int n;
int ok[510],vis[510];
int fun(int a)
{
return a<0?-a:a;
}
bool Find(int x)
{
for (int i=0; i<n; i++)
{
if (Map[x][i]==1&&!vis[i])
{
vis[i]=1;
if (ok[i]==-1)
{
ok[i]=x;
return true;
}
else
{
if (Find(ok[i]))
{
ok[i]=x;
return true;
}
}
}
}
return false;
}
int main()
{
int t;
while (~scanf("%d",&t))
{
while (t--)
{
memset(ok,-1,sizeof(ok));
int q,w,a,b,c,d;
scanf("%d",&n);
for (int i=0; i<n; i++)
{
scanf("%d:%d%d%d%d%d",&q,&w,&a,&b,&c,&d);
int l=q*60+w;
p[i].stime=l;
p[i].sx=a;
p[i].sy=b;
p[i].ex=c;
p[i].ey=d;
p[i].etime=fun(a-c)+fun(b-d);
}
for (int i=0; i<n; i++)
{
for (int j=i+1; j<n; j++)
{
if (p[i].stime+p[i].etime+fun(p[i].ex-p[j].sx)+fun(p[i].ey-p[j].sy)+1<=p[j].stime)
{
Map[i][j]=1;
}
else
Map[i][j]=0;
}
}
int k=0;
for (int i=0;i<n;i++)
{
memset(vis,0,sizeof(vis));
if (Find(i))
k++;
}
printf ("%d\n",n-k);
}
}
return 0;
}
hdu 1350 Taxi Cab Scheme(二分匹配)
标签:
原文地址:http://blog.csdn.net/qiqi_skystar/article/details/50197479