1. 程式人生 > >POJ2060 Taxi Cab Scheme【二分圖最小路徑覆蓋】

POJ2060 Taxi Cab Scheme【二分圖最小路徑覆蓋】

題目連結:

題目大意:

計程車公司每天有有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;
}