bzoj3993: [SDOI2015]星际战争(网络流)

3993: [SDOI2015]星际战争

题目:传送门 

 


 

 

题解:

   洛谷AC了,但是因为bzoj的spj有问题所以暂时没A

   一道老题目了,二分时间然后网络流判断。

   每次st-->武器连时间*攻击力

   武器-->机器人 流量无限

   机器人-->ed 流量为血量值

   精度有点gou...

    


 

 

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define eps 1e-7
 7 #define inf 999999999.0
 8 using namespace std;
 9 struct node
10 {
11     int x,y,next,other;
12     double c;
13 }a[2100000];int len,last[2100000];
14 void ins(int x,int y,double c)
15 {
16     int k1,k2;
17     k1=++len;
18     a[len].x=x;a[len].y=y;a[len].c=c;
19     a[len].next=last[x];last[x]=len;
20     
21     k2=++len;
22     a[len].x=y;a[len].y=x;a[len].c=0;
23     a[len].next=last[y];last[y]=len;
24     
25     a[k1].other=k2;
26     a[k2].other=k1;
27 }
28 int st,ed,n,m,head,tail;
29 int list[2100000],h[2100000];
30 bool bt_h()
31 {
32     memset(h,0,sizeof(h));h[st]=1;
33     list[1]=st;head=1;tail=2;
34     while(head!=tail)
35     {
36         int x=list[head];
37         for(int k=last[x];k;k=a[k].next)
38         {
39             int y=a[k].y;
40             if(!h[y] && a[k].c>0)
41             {
42                 h[y]=h[x]+1;
43                 list[tail++]=y;
44             }
45         }
46         head++;
47     }
48     if(h[ed])return true;
49     return false;
50 }
51 double find_flow(int x,double flow)
52 {
53     if(x==ed)return flow;
54     double s=0,t;
55     for(int k=last[x];k;k=a[k].next)
56     {
57         int y=a[k].y;
58         if(h[y]==h[x]+1 && a[k].c>0 && s<flow)
59         {
60             s+=t=find_flow(y,min(a[k].c,flow-s));
61             a[k].c-=t;a[a[k].other].c+=t;
62         }
63     }
64     if(s==0)h[x]=0;
65     return s;
66 }
67 double A[51],B[51];
68 int map[51][51];
69 bool check(double x)
70 {
71     double sum=0.0,ans=0.0;
72     len=0;memset(last,0,sizeof(last));
73     for(int i=1;i<=m;i++)ins(st,i,x*B[i]);
74     for(int i=1;i<=m;i++)for(int j=1;j<=n;j++)if(map[i][j]==1)ins(i,j+m,inf);
75     for(int i=1;i<=n;i++)ins(i+m,ed,A[i]),sum+=A[i];
76     while(bt_h())ans+=find_flow(st,inf);
77     if(abs(ans-sum)<=eps)return true;
78     return false;
79 }
80 int main()
81 {
82     scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%lf",&A[i]);for(int i=1;i<=m;i++)scanf("%lf",&B[i]);
83     st=n+m+1,ed=st+1;
84     for(int i=1;i<=m;i++)
85         for(int j=1;j<=n;j++)
86             scanf("%d",&map[i][j]);
87     double l=0.0,r=10000000.0,ans=0.0;
88     while(l<=r)
89     {
90         double mid=(l+r)/2;
91         if(check(mid))ans=mid,r=mid-eps;
92         else l=mid+eps;
93     }
94     printf("%.6lf\n",ans);
95     return 0;
96 }

 

posted @ 2018-03-25 20:08  CHerish_OI  阅读(248)  评论(0编辑  收藏  举报