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

来源:互联网 发布:java卸载不了怎么办 编辑:程序博客网 时间:2024/06/11 12:57

题目链接:

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;}


0 0
原创粉丝点击