1 #include<cstdio> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #define N 1008 6 #define M 1000009 7 #define eps 0.00001 8 using namespace std; 9 int S,T,A[N],B[N],f[N][N],n,m,cnt=1,tot,head[N],next[M],u[M],d[N],q[N]; 10 double v[M],sum; 11 void jia1(int a1,int a2,double a3) 12 { 13 cnt++; 14 next[cnt]=head[a1]; 15 head[a1]=cnt; 16 u[cnt]=a2; 17 v[cnt]=a3; 18 return; 19 } 20 void jia(int a1,int a2,double a3) 21 { 22 jia1(a1,a2,a3); 23 jia1(a2,a1,0); 24 return; 25 } 26 bool bfs() 27 { 28 memset(d,0,sizeof(d)); 29 int h=0,t=1; 30 q[1]=S; 31 d[S]=1; 32 for(;h<t;) 33 { 34 h++; 35 int p=q[h]; 36 for(int i=head[p];i;i=next[i]) 37 if(!d[u[i]]&&v[i]) 38 { 39 d[u[i]]=d[p]+1; 40 if(d[T]) 41 return 1; 42 t++; 43 q[t]=u[i]; 44 } 45 } 46 return 0; 47 } 48 double dinic(int s,double f) 49 { 50 if(s==T) 51 return f; 52 double rest=f; 53 for(int i=head[s];i&&rest;i=next[i]) 54 if(v[i]&&d[u[i]]==d[s]+1) 55 { 56 double now=dinic(u[i],min(rest,v[i])); 57 if(!now) 58 d[u[i]]=0; 59 v[i]-=now; 60 v[i^1]+=now; 61 rest-=now; 62 } 63 return f-rest; 64 } 65 void jian(double mid) 66 { 67 cnt=1; 68 memset(head,0,sizeof(head)); 69 for(int i=1;i<=n;i++) 70 jia(i+m,T,A[i]); 71 for(int i=1;i<=m;i++) 72 jia(S,i,B[i]*mid); 73 for(int i=1;i<=m;i++) 74 for(int j=1;j<=n;j++) 75 if(f[i][j]) 76 jia(i,j+m,1000000000); 77 return; 78 } 79 int main() 80 { 81 scanf("%d%d",&n,&m); 82 S=0; 83 T=n+m+1; 84 for(int i=1;i<=n;i++) 85 { 86 scanf("%d",&A[i]); 87 sum+=(double)A[i]; 88 } 89 for(int i=1;i<=m;i++) 90 scanf("%d",&B[i]); 91 for(int i=1;i<=m;i++) 92 for(int j=1;j<=n;j++) 93 scanf("%d",&f[i][j]); 94 double l=0,r=1000000,qq; 95 for(;r-l>eps;) 96 { 97 double mid=(l+r)/2.0; 98 jian(mid); 99 double ans=0; 100 for(;bfs();) 101 ans+=dinic(S,0x7fffffff); 102 if(ans>=(sum-eps)) 103 { 104 qq=mid; 105 r=mid; 106 } 107 else 108 l=mid; 109 } 110 printf("%.6lf\n",qq); 111 return 0; 112 }
二分答案网络流。