1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| #include <iostream> #include <cstring> #include <algorithm> #include <stdio.h>
using namespace std; const int maxn = 52; const int inf = 0x3f3f3f3f; int g[maxn][maxn],w[maxn*maxn][maxn*maxn],la[maxn*maxn],lb[maxn*maxn],match[maxn*maxn]; bool va[maxn*maxn],vb[maxn*maxn];
int n,m,delta;
void init() { memset(match,-1,sizeof match); memset(la,0,sizeof la); memset(lb,0,sizeof lb); }
int dfs(int u) { va[u] = 1; for (int i=0; i<m; ++i) { if (!vb[i]) { if (la[u]+lb[i] == w[u][i]) { vb[i] = 1; if (match[i]==-1 || dfs(match[i])) { match[i] = u; return 1; } } else delta = min(delta,la[u]+lb[i]-w[u][i]); } } return 0; }
double KM() { for (int i=0; i<n; ++i) { while (1) { memset(va,0,sizeof va); memset(vb,0,sizeof vb); delta = inf; if (dfs(i)) break; for (int j=0; j<m; ++j) { if (va[j]) la[j] -= delta; if (vb[j]) lb[j] += delta; } } } double ans = 0.0; for (int i=0; i<m; ++i) if (match[i] != -1) ans += w[match[i]][i]; return -ans; }
int main() { freopen("1.in","r",stdin); int times; scanf("%d",×); while (times--) { init(); scanf("%d%d",&n,&m); for (int i=0; i<n; ++i) for (int j=0; j<m; ++j) scanf("%d",&g[i][j]); for (int i=0; i<n; ++i) for (int k=0; k<n; ++k) for (int j=0; j<m; ++j) w[i][j*n+k] = -(g[i][j]*(k+1)); m = n*m; printf("%.6lf\n",KM()/(1.0*n)); } return 0; }
|