POJ 2060 Taxi Cab Scheme(最小点覆盖)

题目链接

Description

Running a taxi station is not all that simple. Apart from the obvious demand for a centralised coordination of the cabs in order to pick up the customers calling to get a cab as soon as possible,there is also a need to schedule all the taxi rides which have been booked in advance.Given a list of all booked taxi rides for the next day, you want to minimise the number of cabs needed to carry out all of the rides. 
For the sake of simplicity, we model a city as a rectangular grid. An address in the city is denoted by two integers: the street and avenue number. The time needed to get from the address a, b to c, d by taxi is |a - c| + |b - d| minutes. A cab may carry out a booked ride if it is its first ride of the day, or if it can get to the source address of the new ride from its latest,at least one minute before the new ride's scheduled departure. Note that some rides may end after midnight.

Input

On the first line of the input is a single positive integer N, telling the number of test scenarios to follow. Each scenario begins with a line containing an integer M, 0 < M < 500, being the number of booked taxi rides. The following M lines contain the rides. Each ride is described by a departure time on the format hh:mm (ranging from 00:00 to 23:59), two integers a b that are the coordinates of the source address and two integers c d that are the coordinates of the destination address. All coordinates are at least 0 and strictly smaller than 200. The booked rides in each scenario are sorted in order of increasing departure time.

Output

For each scenario, output one line containing the minimum number of cabs required to carry out all the booked taxi rides.

Sample Input

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

Sample Output

1
2

题意:现在有个n辆车的出行表,现在要是有趟车在送完自己的乘客后,要是在另一趟车出发前赶到该趟车的出发点,另一辆车就可以不用跑,这样就可以减少一辆车。问:最少用几辆车可以完成运输。

题解:这个题是一个最小点覆盖问题,最小点覆盖 = | G | - 最大匹配数。所以我们求最大匹配数就行了。先提前处理,每辆车除了完成自己的运输,还能够帮哪些车完成运输,然后在求最大匹配就行了。细节看代码。

#include <iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<stack>
#include<string>
const int maxn=5e2+10;
const int mod=1e9+7;
const int inf=1e8;
#define me(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x&(-x)
#define mid (l+r)/2
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI 3.14159265358979323846
int dir[4][2]= {0,-1,-1,0,0,1,1,0};
typedef long long ll;
using namespace std;
bool vis[maxn];
int d[maxn],n;
int maps[maxn][maxn];
struct node
{
    int t1,t2;///t1表示该趟车的出发时间,t2表示该趟车送完乘客后的时间
    int x1,x2,y1,y2;
}ti[maxn];
int dis_t(int x1,int y1,int x2,int y2)///计算在送乘客的过程中花的时间
{
    return abs(x1-x2)+abs(y1-y2);
}
int found(int u)
{
    for(int i=1;i<=n;i++)
        if(maps[u][i]&&!vis[i])
        {
            vis[i]=1;
            if(d[i]==-1||found(d[i]))
            {
                d[i]=u;
                return 1;
            }
        }
    return 0;
}
int hungry()///求最大匹配
{
    me(d,-1);
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        me(vis,0);
        sum+=found(i);
    }
    return sum;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            int a,b;
            scanf("%d:%d",&a,&b);
            ti[i].t1=a*60+b;///化成分钟数好计算
            scanf("%d%d%d%d",&ti[i].x1,&ti[i].y1,&ti[i].x2,&ti[i].y2);
            ti[i].t2=ti[i].t1+dis_t(ti[i].x1,ti[i].y1,ti[i].x2,ti[i].y2);
        }
        me(maps,0);
        for(int i=1;i<=n;i++)///判断在i趟车送完乘客后能不能在j趟车出发前赶到j趟车的出发点
            for(int j=1;j<=n;j++)
                if(ti[i].t2+dis_t(ti[i].x2,ti[i].y2,ti[j].x1,ti[j].y1)<ti[j].t1)
                    maps[i][j]=1;
        printf("%d\n",n-hungry());///最小点覆盖 = | G | - 最大匹配数
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41292370/article/details/87876329