hdu The Windy's二分图最佳匹配问题
The Windy's
Time Limit : 10000/5000ms (Java/Other) Memory Limit : 131072/65536K (Java/Other)
Total Submission(s) : 9 Accepted Submission(s) : 1
The Windy's is a world famous toy factory that owns M top-class workshop to make toys. This year the manager receives N orders for toys. The manager knows that every order will take different amount of hours in different workshops. More precisely, the i-th order will take Zij hours if the toys are making in the j-th workshop. Moreover, each order's work must be wholly completed in the same workshop. And a workshop can not switch to another order until it has finished the previous one. The switch does not cost any time.
The manager wants to minimize the average of the finishing time of the N orders. Can you help him?
The first line of input is the number of test case. The first line of each test case contains two integers, N and M (1 ≤ N,M ≤ 50). The next N lines each contain M integers, describing the matrix Zij (1 ≤ Zij ≤ 100,000) There is a blank line before each test case.
For each test case output the answer on a single line. The result should be rounded to six decimal places.
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <stack> #include <cmath> #include <algorithm> using namespace std; #define maxn 55 #define inf 1e9 int n,m,t,nn,mm; int map[60][3000]; int lx[maxn],ly[3000],my[3000],slack; bool visx[maxn],visy[3000]; void init(){ scanf("%d%d",&n,&m); for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ int tmp; scanf("%d",&tmp); for(int k=1;k<=n;k++){ map[i][j*n+k-1]=-tmp*k; } } }nn=n;mm=n*m; } bool dfs(int u){ visx[u]=true; for(int v=0;v<mm;v++)if(!visy[v]){ int t=lx[u]+ly[v]-map[u][v]; if(!t){ visy[v]=true; if(my[v]==-1 || dfs(my[v])){ my[v]=u; return true; } }else if(slack>t) slack=t; }return false; } double km(){ double ans=0; for(int i=0;i<nn;i++){ lx[i]=-inf; for(int j=0;j<mm;j++){ if(map[i][j]>lx[i]) lx[i]=map[i][j]; } } for(int j=0;j<mm;j++){ly[j]=0;my[j]=-1;} for(int i=0;i<nn;i++){ while(1){ memset(visx,0,sizeof(visx)); memset(visy,0,sizeof(visy)); slack=inf; if(dfs(i)) break; for(int j=0;j<nn;j++)if(visx[j])lx[j]-=slack; for(int j=0;j<mm;j++)if(visy[j])ly[j]+=slack; } } for(int i=0;i<mm;i++){ if(my[i]!=-1) ans-=map[my[i]][i]; }return ans/n; } int main() { freopen("in.txt","r",stdin); scanf("%d",&t); while(t--){ init(); printf("%.6lf\n",km()); } return 0; }