1 // hdu2236 2 // Graph Match binary search + enumeration + bipartite 3 // Dec.26 2014 4 5 #include <cstdio> 6 #include <cstring> 7 #include <algorithm> 8 9 #define MaxN 111 10 #define ACCEPT 11 12 int G[MaxN][MaxN], T, n, max_edge, min_edge, l, r, mid, enum_edge, gx[MaxN], gy[MaxN]; 13 bool vis[MaxN], is_match; 14 15 bool dfs(int u) 16 { 17 for(int i = 1; i <= n; ++i){ 18 if(G[u][i] >= enum_edge && G[u][i] <= enum_edge + mid && vis[i] == false){ 19 vis[i] = true; 20 if(gy[i] == -1 || dfs(gy[i]) == true){ 21 gy[i] = u; 22 gx[u] = i; 23 return true; 24 } 25 } 26 } 27 return false; 28 } 29 30 bool hungry() 31 { 32 memset(gx, -1, sizeof(gx)); 33 memset(gy, -1, sizeof(gy)); 34 for(int i = 1; i <= n; ++i){ 35 memset(vis, false, sizeof(vis)); 36 if(dfs(i) == false) 37 return false; 38 } 39 } 40 41 int main(int argc, char const *argv[]) 42 { 43 #ifndef ACCEPT 44 freopen("in.txt","r",stdin); 45 #endif 46 scanf("%d", &T); 47 while(T--){ 48 // input , get the max num and min num 49 max_edge = -1; 50 min_edge = 101; 51 scanf("%d", &n); 52 for(int i = 1; i <= n; ++i){ 53 for(int j = 1; j <= n; ++j){ 54 scanf("%d", &G[i][j]); 55 max_edge = std::max(G[i][j], max_edge); 56 min_edge = std::min(G[i][j], min_edge); 57 } 58 } 59 // 60 l = 0; 61 r = max_edge - min_edge; 62 while(true){ 63 mid = (l + r) >> 1; 64 is_match = false; 65 for(enum_edge = min_edge; enum_edge + mid <= max_edge; ++enum_edge){ 66 if(hungry() == true){ 67 is_match = true; 68 break; 69 } 70 } 71 if(is_match == true) 72 r = mid; 73 if(l == mid) 74 break; 75 if(is_match == false) 76 l = mid; 77 } 78 printf("%d ", r); 79 } 80 return 0; 81 }