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

  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 << 31) - 1);
 32 const double eps = 1e-6;
 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 = 1;
 41     while(!isdigit((x = getchar())) && x != '-' && x != -1);
 42     if(x == -1) {
 43         ungetc(x, stdin);
 44         return false;
 45     }
 46     if(x == '-'){
 47         x = getchar();
 48         aFlag = -1;
 49     }
 50     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
 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 = 0, int next = -1, double flow = 0, double cap = 0):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(0), h(NULL) {        }
 72         MapManager(int nodes):ce(0) {
 73             h = new int[(const int)(nodes + 1)];
 74             memset(h, -1, sizeof(int) * (nodes + 1));
 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 == 0)    return;
 84             addEdge(from, end, 0, 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 = 0;
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 + 1)];
129     B = new int[(const int)(m + 1)];
130     atable = Matrix<boolean>(m + 1, n + 1);
131     for(int i = 1; i <= n; i++)
132         readInteger(A[i]), sA += A[i];
133     for(int i = 1; i <= m; i++)
134         readInteger(B[i]);
135     for(int i = 1; i <= m; i++)
136         for(int j = 1; j <= n; j++)
137             readInteger(atable[i][j]);
138     s = 0, t = n + m + 1;
139 }
140
141 MapManager g;
142 inline void mkmap(double mid) {
143     g = MapManager(n + m + 1);
144     for(int i = 1; i <= m; i++)
145         g.addDoubleEdge(s, i, B[i] * mid);
146     for(int i = 1; i <= n; i++)
147         g.addDoubleEdge(i + m, t, A[i]);
148     for(int i = 1; i <= m; i++)
149         for(int j = 1; 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 + 1));
159     que.push(s);
160     vis[s] = true;
161     dis[s] = 0;
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] + 1;
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 = 0;
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] + 1) && (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 ^ 1].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 + 1)];
196     dis = new int[(const int)(t + 1)];
197     cur = new int[(const int)(t + 1)];
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) / 2;
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 0;
227 }

转载于:https://www.cnblogs.com/yyf0309/p/7132779.html

bzoj 3993 星际战争 - 二分答案 - 最大流相关推荐

  1. bzoj3993 [SDOI2015]星际战争 二分答案+网络流检验

    流量分配模型. 这个题如果时间不知道的话流量是未知的,对于流量未知的网络流肯定是没法做的(没有动态借流量的网络流) 由于时间上满足连续性,就可以二分答案,然后流量确定就可以跑网络流 主要还是化静为动 ...

  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 1738: [Usaco2005 mar]Ombrophobic Bovines 发抖的牛( floyd + 二分答案 + 最大流 )

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

  5. 河城荷取 二分答案 最大流

    NKOJ2507 河城荷取 问题描述 在幻想乡,河城荷取是擅长高科技工业的河童.荷取的得意之作除了光学迷彩外,还有震动整个幻想乡的巨型人形『非想天则』.不过由于人形太过巨大,所以为它充能是一件很麻烦的 ...

  6. poj2455 Secret Milking Machine(二分答案+最大流)

    二分答案,双向边网络流,反向边容量直接设为val即可.可以选择的边容量为1,跑最大流,看是否满流(是否存在K条路径). #include <cstdio> #include <cst ...

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

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

  8. 【BZOJ - 3993】星际战争(网络流最大流+二分)

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

  9. 【Luogu-P3324 [SDOI2015] / DSY-1993】星际战争

    传送门:P3324 [SDOI2015]星际战争 二分 + 最大流 Solution\mathfrak{Solution}Solution 1 不可否认,看到题面的第一反应是构造二分图,让武器在一边, ...

最新文章

  1. java读取ppt内容_Java 读取/获取PPT文本
  2. PHP命令行代码更新不及时,PHP脚本从命令行工作,而不是从cron
  3. 学科顶尖!这些高校,“双一流”潜力股!
  4. Flume日志收集系统架构详解--转
  5. android开发版本,Android开发之版本统一规范
  6. Leetcode 1. 两数之和 (Python版)
  7. ant-design官网打不开 , 需要用镜像地址打开
  8. 【设计模式 05】工厂方法模式
  9. 双龙贺岁,龙蜥 LoongArch GA 版正式发布
  10. 清除浮动的七种方式方法(实例代码讲解)
  11. HM67主板开启ACHI
  12. c语言五子棋中怎么设置开局,五子棋教程:指定开局
  13. 在登录页面中输入正确的信息还是显示用户名或密码错误
  14. JavaScript 打印星号三角形
  15. marshmallow——Nested 类型
  16. 融合云信平台对接_java代码
  17. Kali PPPoE 拨号上网
  18. 查看已安装的Python包依赖树
  19. 每日一课 | 详解数据分析最爱用的估算法
  20. 读万卷书,写万行代码

热门文章

  1. pr 剪视频的一些技巧
  2. 教程 参数设置_UG教程之非切削参数设置
  3. 波士顿出新品,10只机器狗拖动大卡车
  4. 快手电商金牛小店自动下单协yi分析
  5. 英语单词_巩固方法草稿A
  6. 查看mysql更新日志_mysql 的日志查看
  7. 软件工程大作业---《苕皮段子》段子笑话APP
  8. 人工智能基础部分3-方差损失函数的概念
  9. 《新侠客英雄传XP》通关简易攻略2
  10. GPT虚拟直播Demo系列(一)|GPT接入直播间实现主播与观众互动