/*
分析:
枚举+二分搜索+二分匹配。
当n==1的时候我用了特殊处理,都不等那一个数字读入
就直接输出结果,然后就WA了一天,囧~~~
注意把二分搜索当外循环、枚举当内循环,否则反过来
的话有可能超时哦~
2012-10-29
*/
分析:
枚举+二分搜索+二分匹配。
当n==1的时候我用了特殊处理,都不等那一个数字读入
就直接输出结果,然后就WA了一天,囧~~~
注意把二分搜索当外循环、枚举当内循环,否则反过来
的话有可能超时哦~
2012-10-29
*/
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#include"math.h"
#define N 111
int n;
int dir[N],k_dir,hash[N],hash_bot[N],num[N];
int map[N][N];
int visit[N],match[N];
struct Eage
{
int from,to,next;
}eage[N*N];
int tot,head[N];
void add(int a,int b)
{
eage[tot].from=a;
eage[tot].to=b;
eage[tot].next=head[a];
head[a]=tot++;
}
void getmap()
{
int i,l;
int t;
tot=0;
memset(head,-1,sizeof(head));
memset(hash,0,sizeof(hash));
memset(hash_bot,0,sizeof(hash_bot));
for(i=0;i<n;i++)
for(l=0;l<n;l++)
{
scanf("%d",&map[i][l]);
hash[map[i][l]]=1;
hash_bot[map[i][l]]=1;
add(i,l);
}
t=0;
for(i=0;i<=100;i++) if(hash[i]) num[t++]=i;
memset(hash,0,sizeof(hash));
for(i=1;i<t;i++)
for(l=0;l<i;l++)
hash[abs(num[i]-num[l])]=1;
for(k_dir=0,i=100;i>=0;i--) if(hash[i]) dir[k_dir++]=i;
if(t==1) dir[k_dir++]=0;
}
int DFS(int k,int bot,int limit)
{
int j,v;
for(j=head[k];j!=-1;j=eage[j].next)
{
v=eage[j].to;
if(visit[v]) continue;
if(map[k][v]<bot) continue;
if(map[k][v]-bot>limit) continue;
visit[v]=1;
if(match[v]==-1 || DFS(match[v],bot,limit))
{
match[v]=k;
return 1;
}
}
return 0;
}
int main()
{
int T;
int i,l;
int low,up,mid;
int flag,ans;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
getmap();
if(n==1) {printf("0\n");continue;}
ans=dir[0];
low=0;up=k_dir-1;mid=(low+up)>>1;
while(low<=up)
{
for(i=0;i<=100;i++)
{
if(hash_bot[i]==0) continue;
flag=1;
memset(match,-1,sizeof(match));
for(l=0;l<n;l++)
{
memset(visit,0,sizeof(visit));
if(DFS(l,i,dir[mid])==0) {flag=0;break;}
}
if(flag) break;
}
if(flag) {ans=ans>dir[mid]?dir[mid]:ans;low=mid+1;}
else up=mid-1;
mid=(low+up)>>1;
}
printf("%d\n",ans);
}
return 0;
}