如果一个出租车在接完一个客人之后还可以接另一位客人,那这两点之间连一条边。
现在突然有个疑问,为什么不用求Floyd?好吧,我明白了,建图过程中就把所有边都连上了,相当于求了一遍Floyd~
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int MAX_N = 500 + 10;
struct Node
{
int t1, t2, x1, y1, x2, y2;
};
struct Edge
{
int v, next;
};
Edge e[MAX_N * (MAX_N - 1)];
Node node[MAX_N];
bool vis[MAX_N];
int head[MAX_N], link[MAX_N];
int n, cnt;
void addEdge(int u, int v)
{
e[cnt].v = v;
e[cnt].next = head[u];
head[u] = cnt++;
}
bool DFS(int u)
{
int v;
for(int i = head[u]; i != -1; i = e[i].next)
{
v = e[i].v;
if(!vis[v])
{
vis[v] = 1;
if(link[v] == -1 || DFS(link[v]))
{
link[v] = u;
return true;
}
}
}
return false;
}
int MaxMatch()
{
int ans = 0;
memset(link, -1, sizeof(link));
for(int i = 0; i < n; i++)
{
memset(vis, 0, sizeof(vis));
if(DFS(i))
ans++;
}
return ans;
}
int dis(int x1, int y1, int x2, int y2)
{
return abs(x2 - x1) + abs(y2 - y1);
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
cnt = 0;
memset(head, -1, sizeof(head));
scanf("%d", &n);
int h, m;
for(int i = 0; i < n; i++)
{
scanf("%d:%d%d%d%d%d", &h, &m, &node[i].x1, &node[i].y1, &node[i].x2, &node[i].y2);
node[i].t1 = h * 60 + m;
node[i].t2 = node[i].t1 + dis(node[i].x1, node[i].y1, node[i].x2, node[i].y2);
}
for(int i = 0; i < n; i++)
for(int j = i + 1; j < n; j++)
if(node[i].t2 + dis(node[i].x2, node[i].y2, node[j].x1, node[j].y1) + 1 <= node[j].t1)
addEdge(i, j);
printf("%d\n", n - MaxMatch());
}
return 0;
}