Codeforces739E. Gosha is hunting

$n \leq 2000$个东西要搬走,两个人分别能搬$a$和$b$件东西,给两个人搬走每种东西的概率,问最优决策下期望搬走多少东西。

一个人搬贡献:$p_i$,另一个人搬贡献:$q_i$,两人一起搬:$p_i+q_i-p_iq_i$。

$s$->两个人:流量分别$a,b$,费用0;两个人->每件东西:费用$p_i$或$q_i$,流量1;每件东西->$t$:两条边,一条流量1费用0,一条流量1费用$-p_iq_i$。跑最大费用流。

  1 //#include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 //#include<time.h>
  5 //#include<complex>
  6 //#include<set>
  7 #include<queue>
  8 #include<algorithm>
  9 #include<stdlib.h>
 10 using namespace std;
 11 
 12 #define LL long long
 13 int qread()
 14 {
 15     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
 16     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
 17 }
 18 
 19 //Pay attention to '-' , LL and double of qread!!!!
 20 
 21 int n,a,b;
 22 #define maxn 6011
 23 #define maxm 50011
 24 
 25 struct Edge{int to,next,cap,flow; double cost;};
 26 struct Network
 27 {
 28     Edge edge[maxm<<1]; int first[maxn],le,n;
 29     void clear(int m) {le=2; n=m;}
 30     void in(int x,int y,int cap,double cost)
 31     {Edge &e=edge[le]; e.to=y; e.cap=cap; e.flow=0; e.cost=cost; e.next=first[x]; first[x]=le++;}
 32     void insert(int x,int y,int cap,double cost) {in(x,y,cap,cost); in(y,x,0,-cost);}
 33     double dis[maxn]; int que[maxn],head,tail,s,t,cur[maxn]; bool vis[maxn];
 34     bool spfa()
 35     {
 36         for (int i=1;i<=n;i++) dis[i]=1e18; dis[s]=0;
 37         vis[s]=1; head=tail=0; que[tail++]=s;
 38         while (head!=tail)
 39         {
 40             int x=que[head++]; if (head==maxn) head=0;
 41             vis[x]=0;
 42             for (int i=first[x];i;i=edge[i].next)
 43             {
 44                 Edge &e=edge[i]; if (e.cap==e.flow) continue;
 45                 if (dis[e.to]-(dis[x]+e.cost)>1e-9)
 46                 {
 47                     dis[e.to]=dis[x]+e.cost;
 48                     if (!vis[e.to])
 49                     {
 50                         que[tail++]=e.to;
 51                         if (tail==maxn) tail=0;
 52                         vis[e.to]=1;
 53                     }
 54                 }
 55             }
 56         }
 57         return dis[t]<1e17;
 58     }
 59     double cost;
 60     int dfs(int x,int a)
 61     {
 62         if (x==t || !a) {cost+=a*dis[t]; return a;}
 63         int flow=0,f;
 64         vis[x]=1;
 65         for (int &i=cur[x];i;i=edge[i].next)
 66         {
 67             Edge &e=edge[i];
 68             if (!vis[e.to] && fabs(dis[e.to]-(dis[x]+e.cost))<1e-9 && (f=dfs(e.to,min(e.cap-e.flow,a)))>0)
 69             {
 70                 e.flow+=f; flow+=f;
 71                 edge[i^1].flow-=f; a-=f;
 72                 if (!a) break;
 73             }
 74         }
 75         vis[x]=0;
 76         return flow;
 77     }
 78     double Dinic(int S,int T)
 79     {
 80         s=S; t=T;
 81         cost=0;
 82         while (spfa())
 83         {
 84             for (int i=1;i<=n;i++) cur[i]=first[i];
 85             dfs(s,0x3f3f3f3f);
 86         }
 87         return cost;
 88     }
 89 //    void test()
 90 //    {
 91 //        for (int i=1;i<=n;i++)
 92 //            for (int j=first[i];j;j=edge[j].next)
 93 //            {
 94 //                Edge &e=edge[j];
 95 //                cout<<i<<"->"<<e.to<<": cap"<<e.cap<<" flow"<<e.flow<<" cost"<<e.cost<<endl;
 96 //            }
 97 //        cout<<endl;
 98 //    }
 99 }g;
100 
101 double p[maxn];
102 int main()
103 {
104     n=qread(); a=qread(); b=qread();
105     int A=n+1,B=A+1,s=B+1,t=s+1; g.clear(t);
106     g.insert(s,A,a,0); g.insert(s,B,b,0);
107     
108     for (int i=1;i<=n;i++) scanf("%lf",&p[i]);
109     double x;
110     for (int i=1;i<=n;i++)
111     {
112         scanf("%lf",&x);
113         g.insert(A,i,1,-p[i]); g.insert(B,i,1,-x);
114         g.insert(i,t,1,0); g.insert(i,t,1,p[i]*x);
115     }
116 //    g.test();
117     printf("%.6f\n",-g.Dinic(s,t));
118 //    g.test();
119     return 0;
120 } 
View Code

 

posted @ 2018-04-27 20:08  Blue233333  阅读(297)  评论(0编辑  收藏  举报