Problem
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/30c44f7169734023240d5f6ae27e7305.jpeg)
Solution
- 可以转化成dag上的最小路径覆盖,dag的最小路径覆盖可以放在二分图上求。
- 对于原图中的a->b,在二分图中连a->b’,dag上的最小覆盖=n-最大匹配(即左部中未匹配点数量,等价于所有覆盖的起点数量)。
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 505;
int n,m,t,e[maxn][maxn],py[maxn],mxer,bg[maxn],ed[maxn];
int fx[maxn],fy[maxn],ex[maxn],ey[maxn];
bool used[maxn];
int getdis(int a,int b,int c,int d){
return abs(c-a)+abs(d-b);
}
bool find(int x){
for (int j=1;j<=n;j++){
if (e[x][j]&&!used[j])
{
used[j]=1;
if (!py[j] || find(py[j])) {
py[j]=x;
return true;
}
}
}
return false;
}
void init()
{
memset(py,0,sizeof(py));
memset(e,0,sizeof(e));
mxer = 0;
}
int main()
{
cin>>t;
while(t--)
{
init();
cin>>n;
for(int i=1;i<=n;i++)
{
int a,b;
scanf("%d:%d",&a,&b);
scanf("%d%d%d%d",&fx[i],&fy[i],&ex[i],&ey[i]);
bg[i] = a*60+b;
ed[i] = bg[i]+getdis(fx[i],fy[i],ex[i],ey[i]);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(ed[i]+getdis(ex[i],ey[i],fx[j],fy[j])<bg[j])
e[i][j] = 1;
}
}
for(int i=1;i<=n;i++)
{
memset(used,0,sizeof(used));
if(find(i)) mxer++;
}
cout<<n-mxer<<endl;
}
return 0;
}