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军团的所有巨型机器人

  二分时间,然后建图,激光武器和源点相连,容量为这个激光武器在这个时间内能够造成的伤害,机器人和汇点连边,容量为机器人的装甲值,激光武器和它能够攻击的目标连一条边,容量为无限大。

Code

 /**
* bzoj
* Problem#3993
* Accepted
* Time:48ms
* Memory:1688k
*/
#include <iostream>
#include <cstdio>
#include <ctime>
#include <cmath>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <stack>
#ifndef WIN32
#define Auto "%lld"
#else
#define Auto "%I64d"
#endif
using namespace std;
typedef bool boolean;
const signed int inf = (signed)((1u << ) - );
const double eps = 1e-;
#define smin(a, b) a = min(a, b)
#define smax(a, b) a = max(a, b)
#define max3(a, b, c) max(a, max(b, c))
#define min3(a, b, c) min(a, min(b, c))
template<typename T>
inline boolean readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-' && x != -);
if(x == -) {
ungetc(x, stdin);
return false;
}
if(x == '-'){
x = getchar();
aFlag = -;
}
for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
ungetc(x, stdin);
u *= aFlag;
return true;
} typedef class Edge {
public:
int end;
int next;
double flow;
double cap;
Edge(int end = , int next = -, double flow = , double cap = ):end(end), next(next), flow(flow), cap(cap) { }
}Edge; typedef class MapManager {
public:
int ce;
vector<Edge> edge;
int* h; MapManager():ce(), h(NULL) { }
MapManager(int nodes):ce() {
h = new int[(const int)(nodes + )];
memset(h, -, sizeof(int) * (nodes + ));
} inline void addEdge(int from, int end, double flow, double cap) {
edge.push_back(Edge(end, h[from], flow, cap));
h[from] = ce++;
} inline void addDoubleEdge(int from, int end, double cap) {
if(cap == ) return;
addEdge(from, end, , cap);
addEdge(end, from, cap, cap);
} Edge& operator [] (int pos) {
return edge[pos];
} inline void clear() {
delete[] h;
edge.clear();
}
}MapManager;
#define m_begin(g, i) (g).h[(i)]
#define m_endpos -1 inline boolean dcmp(double a, double b) {
return fabs(a - b) < eps;
} template<typename T>class Matrix{
public:
T *p;
int lines;
int rows;
Matrix():p(NULL){ }
Matrix(int rows, int lines):lines(lines), rows(rows){
p = new T[(lines * rows)];
}
T* operator [](int pos){
return (p + pos * lines);
}
};
#define matset(m, i, s) memset((m).p, (i), (s) * (m).lines * (m).rows) int n, m;
int *A, *B;
int sA = ;
int s, t;
Matrix<boolean> atable; inline void init() {
readInteger(n);
readInteger(m);
A = new int[(const int)(n + )];
B = new int[(const int)(m + )];
atable = Matrix<boolean>(m + , n + );
for(int i = ; i <= n; i++)
readInteger(A[i]), sA += A[i];
for(int i = ; i <= m; i++)
readInteger(B[i]);
for(int i = ; i <= m; i++)
for(int j = ; j <= n; j++)
readInteger(atable[i][j]);
s = , t = n + m + ;
} MapManager g;
inline void mkmap(double mid) {
g = MapManager(n + m + );
for(int i = ; i <= m; i++)
g.addDoubleEdge(s, i, B[i] * mid);
for(int i = ; i <= n; i++)
g.addDoubleEdge(i + m, t, A[i]);
for(int i = ; i <= m; i++)
for(int j = ; j <= n; j++)
if(atable[i][j])
g.addDoubleEdge(i, j + m, inf);
} int* dis;
boolean* vis;
queue<int> que;
inline boolean bfs() {
memset(vis, false, sizeof(boolean) * (t + ));
que.push(s);
vis[s] = true;
dis[s] = ;
while(!que.empty()) {
int e = que.front();
que.pop();
for(int i = m_begin(g, e); i != m_endpos; i = g[i].next) {
if(dcmp(g[i].cap, g[i].flow)) continue;
int eu = g[i].end;
if(vis[eu]) continue;
vis[eu] = true;
dis[eu] = dis[e] + ;
que.push(eu);
}
}
return vis[t];
} int *cur;
inline double blockedflow(int node, double minf) {
if((node == t) || (minf < eps)) return minf;
double f, flow = ;
for(int& i = cur[node]; i != m_endpos; i = g[i].next) {
int& eu = g[i].end;
if(dis[eu] == (dis[node] + ) && (f = blockedflow(eu, min(minf, g[i].cap - g[i].flow))) >= eps) {
minf -= f;
flow += f;
g[i].flow += f;
g[i ^ ].flow -= f;
if(minf < eps) return flow;
}
}
return flow;
} inline void init_dinic() {
vis = new boolean[(const int)(t + )];
dis = new int[(const int)(t + )];
cur = new int[(const int)(t + )];
} inline boolean dinic(double mid) {
mkmap(mid);
double maxflow = 0.0;
while(bfs()) {
for(int i = s; i <= t; i++)
cur[i] = m_begin(g, i);
maxflow += blockedflow(s, inf);
}
g.clear();
return dcmp(maxflow, sA);
} inline void solve() {
init_dinic();
double l = 0.0, r = sA;
while(l + eps <= r) {
double mid = (l + r) / ;
if(dinic(mid)) r = mid;
else l = mid;
}
printf("%.6lf", r);
} int main() {
init();
solve();
return ;
}

bzoj 3993 星际战争 - 二分答案 - 最大流的更多相关文章

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

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

  2. bzoj 3993 星际战争

    题目大意: X军团和Y军团正在激烈地作战  在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai 当一个巨型机器人的装甲值减少到0或者以下时,这个巨型机 ...

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

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

  4. BZOJ 1570: [JSOI2008]Blue Mary的旅行( 二分答案 + 最大流 )

    二分答案, 然后对于答案m, 把地点分成m层, 对于边(u, v), 第x层的u -> 第x+1层的v 连边. 然后第x层的u -> 第x+1层的u连边(+oo), S->第一层的1 ...

  5. BZOJ 1738: [Usaco2005 mar]Ombrophobic Bovines 发抖的牛( floyd + 二分答案 + 最大流 )

    一道水题WA了这么多次真是.... 统考终于完 ( 挂 ) 了...可以好好写题了... 先floyd跑出各个点的最短路 , 然后二分答案 m , 再建图. 每个 farm 拆成一个 cow 点和一个 ...

  6. BZOJ 1305 CQOI2009 dance跳舞 二分答案+最大流

    题目大意:给定n个男生和n个女生,一些互相喜欢而一些不.举行几次舞会,每次舞会要配成n对.不能有同样的组合出现.每一个人仅仅能与不喜欢的人跳k次舞,求最多举行几次舞会 将一个人拆成两个点.点1向点2连 ...

  7. [bzoj3993][SDOI2015]星际战争-二分+最大流

    Brief Description 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战.在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai. ...

  8. HDU3081(KB11-N 二分答案+最大流)

    Marriage Match II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  9. BZOJ2547 CTSC2002玩具兵(最短路径+二分答案+最大流)

    先不考虑只有一个显得有些特殊的天兵. 可以发现超能力的作用实质上是使兵更换职业.每一个兵到达某个位置最少需要更换职业的次数是彼此独立的,因为如果需要某两人互换职业可以使他们各自以当前职业到达需要到的地 ...

随机推荐

  1. cocos JS 定时器

    cocos2d-js的定时器的创建跟使用: 情况一: var TestLayer = cc.Layer.extend({ sprite:null, ctor:function () { this.sc ...

  2. php实现记住密码下次自动登陆

    这篇博客里面还写到 实现“记住我的登录状态”的功能方法,简言之,就是对首先对session进行用户信息赋值,检测session,失效后,利用cookie对其赋值: 在实现过程中,根据网上一些代码贴,整 ...

  3. 突然pom.xml中引用的jar包出错。

    在你的本地仓库中,用window搜索包含.lastupdated的文件,全部删除!然后再去项目上maven ------update project

  4. LeetCode88.合并两个有序数组

    给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组. 说明: 初始化 nums1 和 nums2 的元素数量分别为 m 和 n. ...

  5. 关于linux下firefox无法播放mp3文件

    起因是发现在线翻译的网站没法发音. F12调出console,发现是没法解码mp3文件. 尝试安装deadbeef包,发现安装之后推荐安装的软件列表中有个名为ffmpeg的包.安装上之后,重启fire ...

  6. Keras 如何利用训练好的神经网络进行预测

    分成两种情况,一种是公开的训练好的模型,下载后可以使用的,一类是自己训练的模型,需要保存下来,以备今后使用. 如果是第一种情况,则参考    http://keras-cn.readthedocs.i ...

  7. 批量下载网站图片的Python实用小工具(下)

    引子 在 批量下载网站图片的Python实用小工具 一文中,讲解了开发一个Python小工具来实现网站图片的并发批量拉取.不过那个工具仅限于特定网站的特定规则,本文将基于其代码实现,开发一个更加通用的 ...

  8. Presto上使用SQL遇到的一些坑

    本文转载自:https://segmentfault.com/a/1190000013120454?utm_source=tag-newest 最近换了新工作,在数据处理方面,公司是用Presto连接 ...

  9. nodejs之pm2自动重启服务

    pm2 start xxx #启动服务器 pm2 list #查看运行状态 pm2 logs #查看日志 pm2 restart xxx #重启应用 pm2 stop xxx #停止应用 监听修改,并 ...

  10. Spring Batch 远程分区和远程分块的区别

    Partitioning is a master/slave step configuration that allows for partitions of data to be processed ...