题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1127
DAG最小路径覆盖 = 点数 - 最大匹配数。
代码:
#include <stdio.h>
#include <ctime>
#include <math.h>
#include <limits.h>
#include <complex>
#include <string>
#include <functional>
#include <iterator>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <bitset>
#include <sstream>
#include <iomanip>
#include <fstream>
#include <iostream>
#include <ctime>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <time.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
using namespace std;
int n;
int p[510][510];
int book[510];
int match[510];
bool vis[510];
bool dfs(int u)
{
for (int i = 1; i <= n; i++)
{
if (book[i] == 0 && p[u][i] == 1)
{
book[i] = 1;
if (match[i] == 0 || dfs(match[i]))
{
match[i] = u;
return true;
}
}
}
return false;
}
struct node
{
int x1, y1, x2, y2;
int st, ed;
}taxi[510];
int get_dis(node a, node b)
{
return abs(a.x2 - b.x1) + abs(a.y2 - b.y1);
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
memset(p, 0, sizeof(p));
memset(match, 0, sizeof(match));
memset(vis, false, sizeof(vis));
scanf("%d", &n);
int a, b, c, d, e, f;
char s[10];
for (int i = 1;i <= n;i++)
{
scanf("%s %d %d %d %d", s, &c, &d, &e, &f);
a = (s[0] - '0') * 10 + (s[1] - '0');
b = (s[3] - '0') * 10 + (s[4] - '0');
// printf(" %d %d %d %d %d %d\n", a, b, c, d, e, f);
taxi[i].st = a * 60 + b;
taxi[i].ed = taxi[i].st + abs(c - e) + abs(d - f);
taxi[i].x1 = c;
taxi[i].y1 = d;
taxi[i].x2 = e;
taxi[i].y2 = f;
}
for (int i = 1;i <= n;i++)
for (int j = 1;j <= n;j++)
{
if (taxi[i].ed + get_dis(taxi[i],taxi[j]) < taxi[j].st)
p[i][j] = 1;
}
int ans = 0;
for (int i = 1; i <= n; i++)
{
memset(book, 0, sizeof(book));
if (dfs(i))
ans++;
}
printf("%d\n", n - ans);
}
return 0;
}