Description

  3333年,在银河系的某星球上,X军团和Y军团正在激烈 地作战。在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai。当一个巨型机器人的装甲值减少到0或 者以下时,这个巨型机器人就被摧毁了。X军团有M个激光武器,其中第i个激光武器每秒可以削减一个巨型机器人Bi的装甲值。激光武器的攻击是连续的。这种 激光武器非常奇怪,一个激光武器只能攻击一些特定的敌人。Y军团看到自己的巨型机器人被X军团一个一个消灭,他们急需下达更多的指令。为了这个目标,Y军 团需要知道X军团最少需要用多长时间才能将Y军团的所有巨型机器人摧毁。但是他们不会计算这个问题,因此向你求助。

Input

  第一行,两个整数,N、M。

  第二行,N个整数,A1、A2…AN。

  第三行,M个整数,B1、B2…BM。

  接下来的M行,每行N个整数,这些整数均为0或者1。这部分中的第i行的第j个整数为0表示第i个激光武器不可以攻击第j个巨型机器人,为1表示第i个激光武器可以攻击第j个巨型机器人。

Output

   一行,一个实数,表示X军团要摧毁Y军团的所有巨型机器人最少需要的时间。输出结果与标准答案的绝对误差不超过10-3即视为正确。

Sample Input

2 2
3 10
4 6
0 1
1 1

Sample Output

1.300000

HINT

【样例说明1】

  战斗开始后的前0.5秒,激光武器1攻击2号巨型机器人,激光武器2攻击1号巨型机器人。1号巨型机器人被完全摧毁,2号巨型机器人还剩余8的装甲值;
接下来的0.8秒,激光武器1、2同时攻击2号巨型机器人。2号巨型机器人被完全摧毁。
对于全部的数据,1<=N, M<=50,1<=Ai<=105,1<=Bi<=1000,输入数据保证X军团一定能摧毁Y军团的所有巨型机器人
 
  二分时间,用网络流判断是否合法。
 #include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const int maxn=;
const int maxm=;
const double eps=1e-;
int cnt=,fir[maxn],to[maxm],nxt[maxm];
double cap[maxm];
void addedge(int a,int b){
nxt[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;
} int G[][];
int A[],B[]; void Build(double k,int n,int m){
int ct=;
for(int i=;i<=m;i++)
for(int j=;j<=n;j++)
if(G[i][j])
cap[++ct]=1e20,cap[++ct]=0.0; for(int i=;i<=m;i++)
cap[++ct]=1.0*B[i]*k,cap[++ct]=0.0; for(int i=;i<=n;i++)
cap[++ct]=1.0*A[i],cap[++ct]=0.0;
} int dis[maxn],gap[maxn],q[maxn],front,back; void BFS(int S,int T){
memset(dis,,sizeof(dis));
front=back=;
dis[T]=;q[back++]=T;
while(front<back){
int node=q[front++];
for(int i=fir[node];i;i=nxt[i]){
if(dis[to[i]])continue;
dis[to[i]]=dis[node]+;
q[back++]=to[i];
}
}
}
double mid;
int path[maxn],fron[maxn];
double ISAP(int S,int T){
double ret=0.0;
BFS(S,T);
for(int i=S;i<=T;i++)gap[dis[i]]++;
int p=S;
double f;
memcpy(fron,fir,sizeof(fir));
while(dis[S]<=T+){
if(p==T){
f=1e20;
while(p!=S){
f=min(f,cap[path[p]]);
p=to[path[p]^];
}
p=T;ret+=f;
while(p!=S){
cap[path[p]]-=f;
cap[path[p]^]+=f;
p=to[path[p]^];
}
}
int &ii=fron[p];
for(;ii;ii=nxt[ii])
if(cap[ii]&&dis[p]==dis[to[ii]]+)
break;
if(ii)
path[p=to[ii]]=ii;
else{
if(--gap[dis[p]]==)break;
int minn=T+;
for(int i=fir[p];i;i=nxt[i])
if(cap[i])
minn=min(minn,dis[to[i]]); ii=fir[p];
++gap[dis[p]=minn+];
if(p!=S)
p=to[path[p]^];
}
}
return ret;
} int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d",&A[i]);
for(int i=;i<=m;i++)
scanf("%d",&B[i]); for(int i=;i<=m;i++)
for(int j=;j<=n;j++)
scanf("%d",&G[i][j]); for(int i=;i<=m;i++)
for(int j=;j<=n;j++)
if(G[i][j]){
addedge(i,j+m);
addedge(j+m,i);
} for(int i=;i<=m;i++)
addedge(,i),addedge(i,); double tot=0.0;
for(int i=;i<=n;i++){
addedge(i+m,n+m+);
addedge(n+m+,i+m);
tot+=A[i];
}
double lo=,hi=1e5;
while(hi-lo>=1e-){
mid=(lo+hi)/2.0;
Build(mid,n,m);
if(fabs(ISAP(,n+m+)-tot)<eps)
hi=mid;
else
lo=mid;
}
printf("%.4lf\n",hi);
return ;
}
  代码中有个细节没处理到,影响了效率,欢迎大家评论(我就懒得改了,额)。

网络流(二分):BZOJ 3993: [SDOI2015]星际战争的更多相关文章

  1. BZOJ 3993: [SDOI2015]星际战争 [二分答案 二分图]

    3993: [SDOI2015]星际战争 题意:略 R1D2T1考了裸二分答案+二分图最大匹配... #include <iostream> #include <cstdio> ...

  2. BZOJ 3993 [SDOI2015]星际战争 | 网络流 二分答案

    链接 BZOJ 3993 题解 这道题挺棵的-- 二分答案t,然后源点向武器连t * b[i], 武器向能攻击的敌人连1, 敌人向汇点连a[i],如果最大流等于所有敌人的a[i]之和则可行. #inc ...

  3. bzoj 3993: [SDOI2015]星际战争

    #include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #def ...

  4. 3993: [SDOI2015]星际战争

    3993: [SDOI2015]星际战争 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 1244  Solved: ...

  5. 【BZOJ】3993: [SDOI2015]星际战争

    题意 \(m\)个人\(n\)个物品,第\(i\)个物品生命值为\(A_i\),第\(i\)个人每秒可以减少一个物品\(B_i\)的生命值,给出一个\(m \times n\)的矩阵,如果\(i\)行 ...

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

    3993: [SDOI2015]星际战争 题目:传送门 题解: 洛谷AC了,但是因为bzoj的spj有问题所以暂时没A 一道老题目了,二分时间然后网络流判断. 每次st-->武器连时间*攻击力 ...

  7. bzoj千题计划131:bzoj3993: [SDOI2015]星际战争

    http://www.lydsy.com/JudgeOnline/problem.php?id=3993 二分答案 源点向武器连 mid*攻击力的边 机器人向汇点连 防御力 的边 武器i能攻击机器人j ...

  8. BZOJ_3993_[SDOI2015]星际战争_二分+网络流

    BZOJ_3993_[SDOI2015]星际战争_二分+网络流 Description 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战.在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进 ...

  9. 【BZOJ3993】[SDOI2015]星际战争 二分+最大流

    [BZOJ3993][SDOI2015]星际战争 Description 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战.在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地 ...

随机推荐

  1. root密码忘记了要怎么搞

    我是根据这几个教程做的,网址如下 http://www.pc6.com/infoview/Article_65979.html http://down.chinaz.com/server/201111 ...

  2. HTML5 History对象,Javascript修改地址栏而不刷新页面(二)

    一.实例说明: $('#btnOne').click(function () { var stateObject = { id: 1 }; var title = "本地首页"; ...

  3. 在线预览文件(pdf)

    1.flash版(借助flexpaper工具) 可以把pdf文件用pdf2swf工具转换成swf文件.下载地址http://www.swftools.org/download.html 转换代码如下: ...

  4. LaTeX 中插入数学公式

    一.常用的数学符号 1.小写希腊字母 \alpha \nu \beta \xi \gamma o \delta \pi \epsilon \rho \zeta \sigma \eta \tau \th ...

  5. iOS 代码分类

    控件分类: 指示器 (ActivityIndicator) 提醒对话框 (AlertView) 按钮 (Button) 日历 (Calendar) 相机 (Camera) 透明指示层 (HUD) 图像 ...

  6. iOS里面如何同时使用开启ARC的库 和 没有开启 ARC的库,ARC 与非 ARC同时存在的问题

    旧工程配置arc方案: 1,直接在targets->build phases中修改compiler Flags,是否支持arc.添加:-fobjc-arc,就可以让旧项目支持arc. 新工程配置 ...

  7. C++中new的用法

    new int;//开辟一个存放整数的存储空间,返回一个指向该存储空间的地址(即指针) new int(100);//开辟一个存放整数的空间,并指定该整数的初值为100,返回一个指向该存储空间的地址 ...

  8. 《zip命令》-linux命令五分钟系列之九

    本原创文章属于<Linux大棚>博客. 博客地址为http://roclinux.cn. 文章作者为roc 希望您能通过捐款的方式支持Linux大棚博客的运行和发展.请见“关于捐款” == ...

  9. web版扫雷小游戏(一)

    作为一名程序猿,平时的爱好也不多,说起游戏,我不太喜欢大型的网游,因为太耗时间,偶尔玩玩经典的单机小游戏,比如windows下自带的游戏扫雷(秀一下,高级下最高纪录110s). 现阶段正在致力于web ...

  10. Fedora 18 安装前指南

    Secure Boot 与 Win 8   随着 Win8 的发布,先前关于 Secure Boot 和 UEFI 的诸多猜测也得到了证实,Fedora 18 也将如同当初计划的那样使用 shim + ...