# Codeforces739E. Gosha is hunting

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

$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
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;
39         {
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 {
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  阅读(251)  评论(0编辑  收藏  举报