Taxi Cab Scheme POJ - 2060 二分图最小路径覆盖

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

OJ-ID:
poj-2060

author:
Caution_X

date of submission:
20191002

tags:
二分图最小点覆盖

description modelling:
给定一个二维坐标图,从一个点a到另一个点b费时(a.x-b.x)+(a.y-b.y),现在有n个出租车订单,每个订单提供起点终点坐标和用车时间,问最少需要几辆出租车才可以在用车时间内接完所有客人

major steps to solve it:
(1) 假设我们派出了n辆出租车,如果两个订单恰好可以由一辆车完成,那么出租车数-1.
(2) 建图:现在以一辆车能否在接完这单并且及时接下下一单为依据建立一个二分图,如果两个订单可以由一辆车接下,那么这两个订单设定成匹配状态
(3) 算出最小路径覆盖(二分图最小路径覆盖:用最少的边覆盖所有的点)
最小路径覆盖=N-二分图最大匹配

AC code:

#include<cstdio>
#include<cstring>
#include<math.h>
using namespace std;
int N;
int line[550][550];
int g[550],used[550];
struct Node{
    int t,h,m,a,b,c,d;
}node[550];
int is_link(Node A,Node B)
{
    int dis1=fabs(A.a-A.c)+fabs(A.b-A.d);
    int dis2=fabs(B.a-A.c)+fabs(B.b-A.d);
    return dis1+dis2+1<=fabs(A.t-B.t)?1:0;
}
bool found(int x)
{
    for(int i=1;i<=N;i++) {
        if(line[x][i]&&!used[i]) {
            used[i]=1;
            if(g[i]==-1||found(g[i])) {
                g[i]=x;
                return true;
            }
        }
    }
    return false;
}
int main()
{
    //freopen("input.txt","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&N);
        memset(line,0,sizeof(line));
        memset(g,-1,sizeof(g));
        for(int i=1;i<=N;i++) {
            int h,m,a,b,c,d;
            scanf("%d:%d %d %d %d %d",&node[i].h,&node[i].m,&node[i].a,&node[i].b,&node[i].c,&node[i].d);
            node[i].t=node[i].h*60+node[i].m;
        }
        for(int i=1;i<=N;i++) {
            for(int j=i+1;j<=N;j++) {
                line[i][j]=is_link(node[i],node[j]);
            }
        }
        int ans=N;
        for(int i=1;i<=N;i++) {
            memset(used,0,sizeof(used));
            if(found(i))    ans--;
        }
        printf("%d\n",ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/cautx/p/11617388.html

时间: 2024-10-02 23:00:31

Taxi Cab Scheme POJ - 2060 二分图最小路径覆盖的相关文章

UVAlive3126 Taxi Cab Scheme(DAG的最小路径覆盖)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=32568 [思路] DAG的最小路径覆盖. 将每个人看做一个结点,如果时间允许到达就连边,则问题转化为DAG上的最小路径覆盖问题,即找到最少的路径使得每个点位于一条路径上. 算法:将DAG中的每个结点u拆分成2个为u1,u2,如果DAG中有边uv则连边u1-v2.如果该二分图的最大匹配数为ans,则答案为n-ans.可以这样想:在一条路径中除尾结点外其他结点都有且仅

UVALive-3126 Taxi Cab Scheme (DAG的最小路径覆盖)

题目大意:要给n个人安排车,已知每个人的出发时间和起点与终点,问最少需要安排几辆车才能完成任务. 题目分析:最小路径覆盖.如果送完a到目的地后能在b出发之前赶来接b,那么连一条有向边a->b,最终将得到一个DAG.最少路径覆盖数便是答案.解法:把所有节点 i 拆成 i 和 i’,如果 i 和 j 之间连有一条边,那么则在二分图中连接 i->j’.最少路径覆盖数便是 n-最大匹配数. 代码如下: # include<iostream> # include<cstdio>

poj 3020 二分图最小路径覆盖

二分图最小路径覆盖=|v|-最大匹配.此题为有向图,切所有边正反向存了两遍,所以结果匹配数要除以2 // // main.cpp // poj3020 // // Created by Fangpin on 15/5/29. // Copyright (c) 2015年 FangPin. All rights reserved. // #include <iostream> #include <cstdio> #include <vector> #include <

POJ 3020 (二分图+最小路径覆盖)

题目链接:http://poj.org/problem?id=3020 题目大意:读入一张地图.其中地图中圈圈代表可以布置卫星的空地.*号代表要覆盖的建筑物.一个卫星的覆盖范围是其周围上下左右四个点.问最少需要几个卫星才能覆盖所有建筑物. 解题思路: 有点类似POJ 1328的覆盖题,不过那题比较简单可以贪心.这题你可以YY试试. 覆盖问题其实可以用图论解决.这题就属于最小路径覆盖,手动由一个点出发连一些路径,这样Hungry就能求出最少需要多少这样的中心点,就可以达成目标了. 本题最大的疑问是

POJ 2594 二分图最小路径覆盖

点击打开链接 题意:将所有点都连起来至少需要多少条路径 思路:二分图的最小路径覆盖,而最小路径覆==图的顶点数-图的最大匹配,而当初还学习过最小顶点覆盖==最大匹配,而最小顶点覆盖需要连双向边,结果除以2,那是因为1-->2时,点1和点2都已经用过,所以我在连一个相应的一条边,代表这两个点不能在用了,样例详见hdu 1054 第二组.而接下来的求最小路径覆盖的最大匹配我们就只能是单向的,这个为什么可以避免呢,因为1-->2-->3这样的话,最小路径为1,但是转化为二分图上的话,对应的点2

POJ 1422 DAG最小路径覆盖

求无向图中能覆盖每个点的最小覆盖数 单独的点也算一条路径 这个还是可以扯到最大匹配数来,原因跟上面的最大独立集一样,如果某个二分图(注意不是DAG上的)的边是最大匹配边,那说明只要取两个端点只要一条边即可. 故最小覆盖数还是 顶点数-最大匹配数 根据DAG建图的时候,就是DAG有边就给对应的端点建边 #include <iostream> #include <cstdio> #include <cstring> using namespace std; int d[15

POJ3216 Repairing Company【二分图最小路径覆盖】【Floyd】

题目链接: http://poj.org/problem?id=3216 题目大意: 有Q个地点,告诉你Q个地点之间的相互距离(从i地点赶到j地点需要的时间).有M项任务, 给你M项任务所在的地点block.开始时间start和任务完成需要时间time.一个工人只有在 他准备完成的下一项任务开始之前完成手上的任务,然后在下一项任务开始之前赶到下一项 任务的地点,才能完成这两项任务.问:最少需要多少个工人来完成这M项任务. 思路: 先用Floyd算出Q个地点之间相互最短距离.然后建立一个二分图,每

POJ2594 Treasure Exploration【二分图最小路径覆盖】【Floyd】

题目链接: http://poj.org/problem?id=2594 题目大意: 给你N个地点,M条有向边,已知构成的图是有向无环图.现在要在地点上放机器人通过M 条边来遍历N个地点,问:最少需要多少个机器人可以遍历N个地点. 思路: 这是一道求最小路径覆盖的题目.和一般最小路径覆盖的题目不一样的地方是:这里的点可 以重复遍历.也就是可以有两个及以上的机器人经过同一个点. 那么,先建立一个二分图, 两边都为N个地点.然后在原图的基础上,用Floyd求一次传递闭包,也就是如果点i可以到达 点j

POJ1422 Air Raid【二分图最小路径覆盖】

题目链接: http://poj.org/problem?id=1422 题目大意: 有N个地点和M条有向街道,现在要在点上放一些伞兵,伞兵可以沿着有向街道走,直到不能走为止. 每条边只能被一个伞兵走一次.问:至少放多少伞兵,能使伞兵可以走到图上所有的点. 思路: 很明显的最小路径覆盖问题.先转换为二分图,先将N个点每个点拆成两个点,左边是1~N个点,右 边也是1~N个点.将有向街道变为左边点指向右边点的边. 因为二分图最小路径覆盖 = 点数 - 二分图最大匹配数,则求出结果就是放的最少伞兵数.