http://poj.org/problem?id=3686
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define maxn 30000 5 using namespace std; 6 7 const int inf=1<<30; 8 int weight[51][maxn],lx[maxn],ly[maxn],match[maxn],a[51][51]; 9 bool sx[maxn],sy[maxn]; 10 11 int n,m; 12 13 bool path(int u) 14 { 15 sx[u]=true; 16 for(int v=1; v<=n*m; v++) 17 { 18 if(!sy[v]&&lx[u]+ly[v]==weight[u][v]) 19 { 20 sy[v]=true; 21 if(!match[v]||path(match[v])) 22 { 23 match[v]=u; 24 return true; 25 } 26 } 27 } 28 return false; 29 } 30 31 int bestmatch() 32 { 33 memset(lx,-inf,sizeof(lx)); 34 memset(ly,0,sizeof(ly)); 35 memset(match,0,sizeof(match)); 36 for(int i=1; i<=n; i++) 37 { 38 for(int j=1; j<=n*m; j++) 39 { 40 lx[i]=max(lx[i],weight[i][j]); 41 } 42 } 43 for(int u=1; u<=n; u++) 44 { 45 while(1) 46 { 47 memset(sx,false,sizeof(sx)); 48 memset(sy,false,sizeof(sy)); 49 if(path(u)) break; 50 int dx=inf; 51 for(int i=1; i<=n; i++) 52 { 53 if(sx[i]) 54 { 55 for(int j=1; j<=n*m; j++) 56 { 57 if(!sy[j]) dx=min(lx[i]+ly[j]-weight[i][j],dx); 58 } 59 } 60 } 61 for(int i=1; i<=n; i++) 62 { 63 if(sx[i]) lx[i]-=dx; 64 } 65 for(int j=1; j<=n*m; j++) 66 { 67 if(sy[j]) ly[j]+=dx; 68 } 69 } 70 71 } 72 int sum=0; 73 for(int i=1; i<=n*m; i++) 74 sum+=weight[match[i]][i]; 75 return -sum; 76 } 77 int main() 78 { 79 int T; 80 scanf("%d",&T); 81 while(T--) 82 { 83 scanf("%d%d",&n,&m); 84 for(int i=1; i<=n; i++) 85 { 86 for(int j=1; j<=m; j++) 87 { 88 scanf("%d",&a[i][j]); 89 } 90 } 91 for(int i=1; i<=n; i++) 92 { 93 for(int j=1; j<=n; j++) 94 { 95 for(int k=1; k<=m; k++) 96 { 97 weight[i][(k-1)*n+j]=-a[i][k]*j; 98 } 99 } 100 } 101 printf("%.6f ",1.0*bestmatch()/n); 102 } 103 return 0; 104 }