您的位置:首页 > 其它

POJ2060 Taxi Cab Scheme【二分图最小路径覆盖】

2015-04-03 23:58 399 查看
题目链接:

http://poj.org/problem?id=2060

题目大意:

出租车公司每天有有N项预约,每项预约有开始时间(xx:xx),出发地点(a,b)与目的地点(c,d)。

完成这项预约行驶需要的时间是|a-c| + |b-d|分钟。一辆车可以在完成一个预约i后再去完成另一

个预约j。条件就是需要再预约j开始时间的前1分钟达到出发地点。问:最少需要多少辆车能完成

所有的预约。

思路:

二分图最小路径覆盖问题。根据题意,我们可以建立一个二分图,两边分别为N项预约。对于两个

预约i和j,如果能在完成预约i后有时间赶去完成预约j,就建立一条i指向j的边。因为开始时间有先

后,那么这个图是有向无环图。如果一辆车可以顺着一条路径由i经过若干条边和若干个点到点j,

则该路径上所有的预约就只需要用一辆车就可以完成预约。那么问题就变为了:求该二分图最小路

径覆盖问题。而二分图最小路径 = 总点数 - 二分图最大匹配,用匈牙利算法求出二分图最大匹配就

可以得到结果了。

AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
using  namespace std;
const int MAXN = 550;

struct Node
{
int time;
int a,b,c,d;
}Dot[MAXN];

int Dist(Node x,Node y)
{
return abs(x.a-y.c) + abs(x.b-y.d);
}

bool Map[MAXN][MAXN],Mask[MAXN];
int NX,NY;
int cx[MAXN],cy[MAXN];

int FindPath(int u)
{
for(int i = 1; i <= NY; ++i)
{
if(Map[u][i] && !Mask[i])
{
Mask[i] = 1;
if(cy[i] == -1 || FindPath(cy[i]))
{
cy[i] = u;
cx[u] = i;
return 1;
}
}
}
return 0;
}

int MaxMatch()
{
for(int i = 1; i <= NX; ++i)
cx[i] = -1;
for(int i = 1; i <= NY; ++i)
cy[i] = -1;

int res = 0;
for(int i = 1; i <= NX; ++i)
{
if(cx[i] == -1)
{
for(int j = 1; j <= NY; ++j)
Mask[j] = 0;
res += FindPath(i);
}
}
return res;
}

int main()
{
int T,N,h,s;
scanf("%d",&T);
while(T--)
{
scanf("%d",&N);
for(int i = 1; i <= N; ++i)
{
scanf("%d:%d %d %d %d %d",&h,&s,&Dot[i].a,&Dot[i].b,&Dot[i].c,&Dot[i].d);
Dot[i].time = h*60+s;
}

memset(Map,0,sizeof(Map));
for(int i = 1; i <= N; ++i)
{
for(int j = i+1; j <= N; ++j)
{
if(Dot[i].time + Dist(Dot[i],Dot[i]) + Dist(Dot[j],Dot[i]) < Dot[j].time)
Map[i][j] = 1;
}
}
NX = NY = N;
printf("%d\n",N-MaxMatch());
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: