版权声明: https://blog.csdn.net/yyy_3y/article/details/80012584
思路: 添加一些(n+1-m 个)假广告与不必填坑位匹配,check 条件最大匹配
=n+1,因此可以直接二分图匹配。
#include<bits/stdc++.h>
using namespace std;
const int N=500;
int tx[N],ty[N];
int w[N][N],match[N],vis[N];
int n,m;
void add_edge()
{
memset(w,0,sizeof w);
for(int i=1;i<=m;i++){
for(int j=1;j<n;j++){
w[i][j]=max(fabs(tx[j]-ty[i]),fabs(tx[j+1]-ty[i]));
}
}
for(int i=1;i<=m;i++){
w[i][0]=abs(tx[1]-ty[i]);
w[i][n]=abs(tx[n]-ty[i]);
}
for(int i=m+1;i<=n+1;i++){
for(int j=1;j<n;j++){
w[i][j]=abs(tx[j+1]-tx[j]);
}
}
}
int dfs(int now,int val)
{
for(int i=0;i<=n;i++){
if(!vis[i] && w[now][i]<=val){
vis[i]=1;
if(match[i]==-1 || dfs(match[i],val)) {
match[i]=now;
return 1;
}
}
}
return 0;
}
bool check(int val)
{
int ans=0;
memset(match,-1,sizeof match);
for(int i=1;i<=n+1;i++){
memset(vis,0,sizeof vis);
if(dfs(i,val)) ans++;
}
if(ans==n+1) return 1;
return 0;
}
int main ()
{
//yyy_3y
int T; scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&tx[i]);
for(int i=1;i<=m;i++) scanf("%d",&ty[i]);
add_edge();
int l=0, r=1e9+7;
while(l<=r){
int mid=(l+r)/2;
if(check(mid)) r=mid-1;
else l=mid+1;
}
printf("%d\n",l);
}
return 0;
}