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 }

二分答案网络流。

posted on 2016-03-23 05:42  xiyuedong  阅读(328)  评论(1编辑  收藏  举报