题意:在一个n*n的矩阵中,找n个数使得这n个数都在不同的行和列里并且要求这n个数中的最大值和最小值的差值最小。
分析: 二分枚举差值,如果满足完全匹配则该差值符合。
#include<stdio.h> #include<string.h> #define clr(x)memset(x,0,sizeof(x)) int g[105][105]; int link[105]; int v[105]; int n; int res; int mid,p; int find(int x) { int i; for(i=1;i<=n;i++) { if((!v[i])&&(g[x][i]>=p)&&(g[x][i]<=p+mid)) { v[i]=1; if(link[i]==0||find(link[i])) { link[i]=x; return 1; } } } return 0; } int ok(int x) { int i; clr(link); for(i=1;i<=n;i++) { clr(v); if(find(i)==0) return 0; } return 1; } int main() { int t,i,j,mi,ma,flag,l,r; scanf("%d",&t); while(t--) { mi=101; ma=0; scanf("%d",&n); for(i=1;i<=n;i++) for(j=1;j<=n;j++) { scanf("%d",&g[i][j]); if(g[i][j]>ma) ma=g[i][j]; if(g[i][j]<mi) mi=g[i][j]; } res=101; r=ma-mi; l=0; while(l<=r) { flag=0; mid=(l+r)>>1; for(p=mi;p+mid<=ma;p++) if(ok(p)) { flag=1; break; } if(flag) { res=mid; r=mid-1; } else l=mid+1; } printf("%d\n",res); } return 0; }