1 #include <iostream>
2 #include <cstring>
3 #include <cstdio>
4 #include <cmath>
5 using namespace std;
6 const int maxn=2510;
7 const int maxm=6010;
8 const double eps=1e-8;
9 int cnt=1,fir[maxn],to[maxm],nxt[maxm];
10 double cap[maxm];
11 void addedge(int a,int b){
12 nxt[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;
13 }
14
15 int G[51][51];
16 int A[51],B[51];
17
18 void Build(double k,int n,int m){
19 int ct=1;
20 for(int i=1;i<=m;i++)
21 for(int j=1;j<=n;j++)
22 if(G[i][j])
23 cap[++ct]=1e20,cap[++ct]=0.0;
24
25 for(int i=1;i<=m;i++)
26 cap[++ct]=1.0*B[i]*k,cap[++ct]=0.0;
27
28 for(int i=1;i<=n;i++)
29 cap[++ct]=1.0*A[i],cap[++ct]=0.0;
30 }
31
32 int dis[maxn],gap[maxn],q[maxn],front,back;
33
34 void BFS(int S,int T){
35 memset(dis,0,sizeof(dis));
36 front=back=1;
37 dis[T]=1;q[back++]=T;
38 while(front<back){
39 int node=q[front++];
40 for(int i=fir[node];i;i=nxt[i]){
41 if(dis[to[i]])continue;
42 dis[to[i]]=dis[node]+1;
43 q[back++]=to[i];
44 }
45 }
46 }
47 double mid;
48 int path[maxn],fron[maxn];
49 double ISAP(int S,int T){
50 double ret=0.0;
51 BFS(S,T);
52 for(int i=S;i<=T;i++)gap[dis[i]]++;
53 int p=S;
54 double f;
55 memcpy(fron,fir,sizeof(fir));
56 while(dis[S]<=T+1){
57 if(p==T){
58 f=1e20;
59 while(p!=S){
60 f=min(f,cap[path[p]]);
61 p=to[path[p]^1];
62 }
63 p=T;ret+=f;
64 while(p!=S){
65 cap[path[p]]-=f;
66 cap[path[p]^1]+=f;
67 p=to[path[p]^1];
68 }
69 }
70 int &ii=fron[p];
71 for(;ii;ii=nxt[ii])
72 if(cap[ii]&&dis[p]==dis[to[ii]]+1)
73 break;
74 if(ii)
75 path[p=to[ii]]=ii;
76 else{
77 if(--gap[dis[p]]==0)break;
78 int minn=T+1;
79 for(int i=fir[p];i;i=nxt[i])
80 if(cap[i])
81 minn=min(minn,dis[to[i]]);
82
83 ii=fir[p];
84 ++gap[dis[p]=minn+1];
85 if(p!=S)
86 p=to[path[p]^1];
87 }
88 }
89 return ret;
90 }
91
92 int main(){
93 int n,m;
94 scanf("%d%d",&n,&m);
95 for(int i=1;i<=n;i++)
96 scanf("%d",&A[i]);
97 for(int i=1;i<=m;i++)
98 scanf("%d",&B[i]);
99
100 for(int i=1;i<=m;i++)
101 for(int j=1;j<=n;j++)
102 scanf("%d",&G[i][j]);
103
104 for(int i=1;i<=m;i++)
105 for(int j=1;j<=n;j++)
106 if(G[i][j]){
107 addedge(i,j+m);
108 addedge(j+m,i);
109 }
110
111 for(int i=1;i<=m;i++)
112 addedge(0,i),addedge(i,0);
113
114 double tot=0.0;
115 for(int i=1;i<=n;i++){
116 addedge(i+m,n+m+1);
117 addedge(n+m+1,i+m);
118 tot+=A[i];
119 }
120 double lo=0,hi=1e5;
121 while(hi-lo>=1e-4){
122 mid=(lo+hi)/2.0;
123 Build(mid,n,m);
124 if(fabs(ISAP(0,n+m+1)-tot)<eps)
125 hi=mid;
126 else
127 lo=mid;
128 }
129 printf("%.4lf\n",hi);
130 return 0;
131 }