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

  1. 2 2
  2. 3 10
  3. 4 6
  4. 0 1
  5. 1 1

Sample Output

  1. 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

  1. /**
  2. * bzoj
  3. * Problem#3993
  4. * Accepted
  5. * Time:48ms
  6. * Memory:1688k
  7. */
  8. #include <iostream>
  9. #include <cstdio>
  10. #include <ctime>
  11. #include <cmath>
  12. #include <cctype>
  13. #include <cstring>
  14. #include <cstdlib>
  15. #include <fstream>
  16. #include <sstream>
  17. #include <algorithm>
  18. #include <map>
  19. #include <set>
  20. #include <stack>
  21. #include <queue>
  22. #include <vector>
  23. #include <stack>
  24. #ifndef WIN32
  25. #define Auto "%lld"
  26. #else
  27. #define Auto "%I64d"
  28. #endif
  29. using namespace std;
  30. typedef bool boolean;
  31. const signed int inf = (signed)((1u << ) - );
  32. const double eps = 1e-;
  33. #define smin(a, b) a = min(a, b)
  34. #define smax(a, b) a = max(a, b)
  35. #define max3(a, b, c) max(a, max(b, c))
  36. #define min3(a, b, c) min(a, min(b, c))
  37. template<typename T>
  38. inline boolean readInteger(T& u){
  39. char x;
  40. int aFlag = ;
  41. while(!isdigit((x = getchar())) && x != '-' && x != -);
  42. if(x == -) {
  43. ungetc(x, stdin);
  44. return false;
  45. }
  46. if(x == '-'){
  47. x = getchar();
  48. aFlag = -;
  49. }
  50. for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
  51. ungetc(x, stdin);
  52. u *= aFlag;
  53. return true;
  54. }
  55.  
  56. typedef class Edge {
  57. public:
  58. int end;
  59. int next;
  60. double flow;
  61. double cap;
  62. Edge(int end = , int next = -, double flow = , double cap = ):end(end), next(next), flow(flow), cap(cap) { }
  63. }Edge;
  64.  
  65. typedef class MapManager {
  66. public:
  67. int ce;
  68. vector<Edge> edge;
  69. int* h;
  70.  
  71. MapManager():ce(), h(NULL) { }
  72. MapManager(int nodes):ce() {
  73. h = new int[(const int)(nodes + )];
  74. memset(h, -, sizeof(int) * (nodes + ));
  75. }
  76.  
  77. inline void addEdge(int from, int end, double flow, double cap) {
  78. edge.push_back(Edge(end, h[from], flow, cap));
  79. h[from] = ce++;
  80. }
  81.  
  82. inline void addDoubleEdge(int from, int end, double cap) {
  83. if(cap == ) return;
  84. addEdge(from, end, , cap);
  85. addEdge(end, from, cap, cap);
  86. }
  87.  
  88. Edge& operator [] (int pos) {
  89. return edge[pos];
  90. }
  91.  
  92. inline void clear() {
  93. delete[] h;
  94. edge.clear();
  95. }
  96. }MapManager;
  97. #define m_begin(g, i) (g).h[(i)]
  98. #define m_endpos -1
  99.  
  100. inline boolean dcmp(double a, double b) {
  101. return fabs(a - b) < eps;
  102. }
  103.  
  104. template<typename T>class Matrix{
  105. public:
  106. T *p;
  107. int lines;
  108. int rows;
  109. Matrix():p(NULL){ }
  110. Matrix(int rows, int lines):lines(lines), rows(rows){
  111. p = new T[(lines * rows)];
  112. }
  113. T* operator [](int pos){
  114. return (p + pos * lines);
  115. }
  116. };
  117. #define matset(m, i, s) memset((m).p, (i), (s) * (m).lines * (m).rows)
  118.  
  119. int n, m;
  120. int *A, *B;
  121. int sA = ;
  122. int s, t;
  123. Matrix<boolean> atable;
  124.  
  125. inline void init() {
  126. readInteger(n);
  127. readInteger(m);
  128. A = new int[(const int)(n + )];
  129. B = new int[(const int)(m + )];
  130. atable = Matrix<boolean>(m + , n + );
  131. for(int i = ; i <= n; i++)
  132. readInteger(A[i]), sA += A[i];
  133. for(int i = ; i <= m; i++)
  134. readInteger(B[i]);
  135. for(int i = ; i <= m; i++)
  136. for(int j = ; j <= n; j++)
  137. readInteger(atable[i][j]);
  138. s = , t = n + m + ;
  139. }
  140.  
  141. MapManager g;
  142. inline void mkmap(double mid) {
  143. g = MapManager(n + m + );
  144. for(int i = ; i <= m; i++)
  145. g.addDoubleEdge(s, i, B[i] * mid);
  146. for(int i = ; i <= n; i++)
  147. g.addDoubleEdge(i + m, t, A[i]);
  148. for(int i = ; i <= m; i++)
  149. for(int j = ; j <= n; j++)
  150. if(atable[i][j])
  151. g.addDoubleEdge(i, j + m, inf);
  152. }
  153.  
  154. int* dis;
  155. boolean* vis;
  156. queue<int> que;
  157. inline boolean bfs() {
  158. memset(vis, false, sizeof(boolean) * (t + ));
  159. que.push(s);
  160. vis[s] = true;
  161. dis[s] = ;
  162. while(!que.empty()) {
  163. int e = que.front();
  164. que.pop();
  165. for(int i = m_begin(g, e); i != m_endpos; i = g[i].next) {
  166. if(dcmp(g[i].cap, g[i].flow)) continue;
  167. int eu = g[i].end;
  168. if(vis[eu]) continue;
  169. vis[eu] = true;
  170. dis[eu] = dis[e] + ;
  171. que.push(eu);
  172. }
  173. }
  174. return vis[t];
  175. }
  176.  
  177. int *cur;
  178. inline double blockedflow(int node, double minf) {
  179. if((node == t) || (minf < eps)) return minf;
  180. double f, flow = ;
  181. for(int& i = cur[node]; i != m_endpos; i = g[i].next) {
  182. int& eu = g[i].end;
  183. if(dis[eu] == (dis[node] + ) && (f = blockedflow(eu, min(minf, g[i].cap - g[i].flow))) >= eps) {
  184. minf -= f;
  185. flow += f;
  186. g[i].flow += f;
  187. g[i ^ ].flow -= f;
  188. if(minf < eps) return flow;
  189. }
  190. }
  191. return flow;
  192. }
  193.  
  194. inline void init_dinic() {
  195. vis = new boolean[(const int)(t + )];
  196. dis = new int[(const int)(t + )];
  197. cur = new int[(const int)(t + )];
  198. }
  199.  
  200. inline boolean dinic(double mid) {
  201. mkmap(mid);
  202. double maxflow = 0.0;
  203. while(bfs()) {
  204. for(int i = s; i <= t; i++)
  205. cur[i] = m_begin(g, i);
  206. maxflow += blockedflow(s, inf);
  207. }
  208. g.clear();
  209. return dcmp(maxflow, sA);
  210. }
  211.  
  212. inline void solve() {
  213. init_dinic();
  214. double l = 0.0, r = sA;
  215. while(l + eps <= r) {
  216. double mid = (l + r) / ;
  217. if(dinic(mid)) r = mid;
  218. else l = mid;
  219. }
  220. printf("%.6lf", r);
  221. }
  222.  
  223. int main() {
  224. init();
  225. solve();
  226. return ;
  227. }

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. MYSQL 5.7修改密码,登录问题

    mysql5.7 关于密码问题 报错: ERROR 1862 (HY000): Your password has expired. To log in you must change it usin ...

  2. aop编程之前置通知

    aop( Aspect-Oriented Programming)前置通知原理案例讲解 编程步骤: 定义接口 编写对象(被代理的对象即目标对象) 编写通知(前置通知即目标方法调用前调用) 在beans ...

  3. 软工网络15团队作业4——Alpha阶段敏捷冲刺8.0

    软工网络15团队作业4--Alpha阶段敏捷冲刺8.0 1.每天举行站立式会议,提供当天站立式会议照片一张. 2.项目每个成员的昨天进展.存在问题.今天安排. 2.1 任务完成安排: 成员 昨日已完成 ...

  4. <6>Lua元表和冒号 self

    Lua中没有像C.C++.JAVA中的类概念,面向对象等 ,但我们可以模拟出来 1. Lua中有个很重要的概念元表 设置元表setmetatable()函数  获取元表getmetatable()函数 ...

  5. Vue系列之 => 自定义键盘修饰符

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 文件格式(图像 IO 14.3)

    文件格式 图片加载性能取决于加载大图的时间和解压小图时间的权衡.很多苹果的文档都说PNG是iOS所有图片加载的最好格式.但这是极度误导的过时信息了. PNG图片使用的无损压缩算法可以比使用JPEG的图 ...

  7. python 序列化,反序列化

    附: pickle 有大量的配置选项和一些棘手的问题.对于最常见的使用场景,你不需要去担心这个,是如果你要在一个重要的程序中使用pickle 去做序列化的话,最好去查阅一下官方文档. https:// ...

  8. 基于FPGA摄像头图像采集显示系统

    本系统主要由FPGA主控模块.图像采集模块.图像存储模块以及图像显示模块等模块组成.其中图像采集模块选择OV7670摄像头模块,完成对视频图像的采集和解码功能,并以RGB565标准输出RGB 5:6: ...

  9. flask模板应用-javaScript和CSS中jinja2

    当程序逐渐变大时,很多时候我们需要在javaScript和CSS代码中使用jinja2提供的变量值,甚至是控制语句.比如,通过传入模板的theme_color变量来为页面设置主题色彩,或是根据用户是否 ...

  10. javamail发送邮件及错误解决方法javax.mail.AuthenticationFailedException: failed to connect, no password specified?

    javamail发送邮件及错误解决方法javax.mail.AuthenticationFailedException: failed to connect, no password specifie ...