分析:只需要用二分找一个区间,然后不断枚举这个区间是否可以达到最大匹配,一直二分到答案为止。
代码:
====================================================================================
#include<stdio.h> #include<string.h> const int MAXN = 107; const int oo = 1e9+7; int G[MAXN][MAXN], Ly[MAXN]; int Max, Min, N; bool used[MAXN]; bool Find(int i) { for(int j=1; j<=N; j++) { if(!used[j] && G[i][j] >= Min && G[i][j] <= Max) { used[j] = true; if(!Ly[j] || Find(Ly[j])) { Ly[j] = i; return true; } } } return false; } int XYL() { memset(Ly, 0, sizeof(Ly)); int ans = 0; for(int i=1; i<=N; i++) { memset(used, false, sizeof(used)); if(Find(i) == true) ans++; } return ans; } int main() { int T; scanf("%d", &T); while(T--) { int i, j, MinL=oo, MaxR=-oo; scanf("%d", &N); for(i=1; i<=N; i++) for(j=1; j<=N; j++) { scanf("%d", &G[i][j]); if(MinL > G[i][j])MinL = G[i][j]; if(MaxR < G[i][j])MaxR = G[i][j]; } int L=0, R=MaxR-MinL, ans=0; while(L <= R) { int Mid = (R+L)>>1; for(i=0; i<=MaxR-Mid; i++) { Min = i, Max = i+Mid; if(XYL() == N)break; } if(i <= MaxR-Mid) { ans = Mid; R = Mid-1; } else L = Mid+1; } printf("%d ", ans); } return 0; }