想说的话
一开始理解错了。。。墨迹了半天不知道咋做。
然后回头去做二分图的作业,才忽然惊醒。。。n行对n列建二分图,直接跑最大匹配找minn跟maxx。然后就T了。
匈牙利的效率果然靠不住。
考虑优化,可以用二分,这里先二分差值,再跑二分图,如果能匹配上,证明答案小了,反之则答案大了。这样是O(nlogn)的。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define ms(x) memset(x,0,sizeof(x))
#define inf 0x3f3f3f3f
#define mf(x) memset(x,inf,sizeof(x))
#define mf1(x) memset(x,-1,sizeof(x))
using namespace std;
const int maxn = 100+10;
const int maxm = 10000+10;
int uu, vv;
int a[maxn][maxn];
bool used[maxn];
int girl[maxn];
bool dfs(int u,int l,int r){
for(int v=1; v<=uu; v++){
if(a[u][v]>=l && a[u][v]<=r && !used[v]){
used[v]=true;
if(girl[v]==-1||dfs(girl[v],l,r)){
girl[v]=u;
return 1;
}
}
}
return 0;
}
bool Dfs(int mid,int l,int r){
int res=0;
mf1(girl);
for(int u=1;u<=uu;u++){
ms(used);
if(!dfs(u,l,r)) return 0;
}
return 1;
}
bool check(int mid){
for(int i=0;i+mid<=100;i++){
if(Dfs(mid,i,i+mid)){
return 1;
}
}
return 0;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
int n;
scanf("%d", &n);
uu = vv = n;
int minn=inf,maxx=-1;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++){
scanf("%d",&a[i][j]);
minn=min(minn,a[i][j]);
maxx=max(maxx,a[i][j]);
}
int l=0,r=maxx-minn;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid)){
r=mid-1;
}
else l=mid+1;
}
printf("%d
", l);
}
return 0;
}