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

来源:互联网 发布:mac os x输入法切换 编辑:程序博客网 时间:2024/05/19 13:19

题目大意:有n项任务,给出每项任务的出发时间,出发地点和目的地。
当一个任务完成之后,如果 当前时间 + 到达另一个任务的出发地的时间 <= 另一个任务的出发时间 - 1 的话,那么就可以让这个人接下去完成这个任务了
问至少需要派多少人才可以完成任务

解题思路:这题和 poj-3216 Repairing Company很像
两个点集都是任务,如果一个任务完成了可以接下来完成另一个任务的话,那么这两个任务之间就存在关系了,这样二分图就建成了
因为要把所有的任务都完成,也就是说要覆盖所有点,这就变成了二分图的最小路径覆盖了

#include<cstdio>#include<cstring>#include<vector>#include<cstdlib>using namespace std;const int N = 510;struct Time {    int h, m, a, b, c, d;}time[N];int vis[N], link[N], n;vector<int> g[N];bool judge(int i, int j) {    int t = abs(time[i].a - time[i].c) + abs(time[i].b - time[i].d) + abs(time[j].a - time[i].c) + abs(time[j].b - time[i].d);    if(time[j].h * 60 + time[j].m - (time[i].h * 60 + time[i].m + t)  >= 1)        return true;    return false;}bool dfs(int u) {    for(int i = 0; i < g[u].size(); i++) {        int v = g[u][i];        if(vis[v])            continue;        vis[v] = 1;        if(link[v] == -1 || dfs(link[v])) {            link[v] = u;            return true;        }    }    return false;}void hungary() {    int ans = 0;    for(int i = 0; i < n; i++) {        memset(vis, 0, sizeof(vis));        if(dfs(i))            ans++;    }    printf("%d\n", n - ans);}void init() {    scanf("%d", &n);    for(int i = 0; i < n; i++) {        scanf("%d:%d%d%d%d%d",&time[i].h, &time[i].m, &time[i].a, &time[i].b, &time[i].c, &time[i].d);    }    for(int i = 0; i < n; i++) {        g[i].clear();        for(int j = 0; j < n; j++)  {            if(i != j && judge(i,j)) {                g[i].push_back(j);            }        }    }    memset(link, -1, sizeof(link));}int main() {    int test;    scanf("%d", &test);    while(test--) {        init();        hungary();    }    return 0;}
0 0