bzoj 3993 星际战争 - 二分答案 - 最大流
3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战。在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai。当一个巨型机器人的装甲值减少到0或者以下时,这个巨型机器人就被摧毁了。X军团有M个激光武器,其中第i个激光武器每秒可以削减一个巨型机器人Bi的装甲值。激光武器的攻击是连续的。这种激光武器非常奇怪,一个激光武器只能攻击一些特定的敌人。Y军团看到自己的巨型机器人被X军团一个一个消灭,他们急需下达更多的指令。为了这个目标,Y军团需要知道X军团最少需要用多长时间才能将Y军团的所有巨型机器人摧毁。但是他们不会计算这个问题,因此向你求助。
Input
第一行,两个整数,N、M。
Output
一行,一个实数,表示X军团要摧毁Y军团的所有巨型机器人最少需要的时间。输出结果与标准答案的绝对误差不超过10-3即视为正确。
Sample Input
2 2
3 10
4 6
0 1
1 1
Sample Output
1.300000
Hint
【样例说明1】
二分时间,然后建图,激光武器和源点相连,容量为这个激光武器在这个时间内能够造成的伤害,机器人和汇点连边,容量为机器人的装甲值,激光武器和它能够攻击的目标连一条边,容量为无限大。
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 星际战争 - 二分答案 - 最大流的更多相关文章
- BZOJ 3993: [SDOI2015]星际战争 [二分答案 二分图]
3993: [SDOI2015]星际战争 题意:略 R1D2T1考了裸二分答案+二分图最大匹配... #include <iostream> #include <cstdio> ...
- bzoj 3993 星际战争
题目大意: X军团和Y军团正在激烈地作战 在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai 当一个巨型机器人的装甲值减少到0或者以下时,这个巨型机 ...
- 【BZOJ3993】[SDOI2015]星际战争 二分+最大流
[BZOJ3993][SDOI2015]星际战争 Description 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战.在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地 ...
- BZOJ 1570: [JSOI2008]Blue Mary的旅行( 二分答案 + 最大流 )
二分答案, 然后对于答案m, 把地点分成m层, 对于边(u, v), 第x层的u -> 第x+1层的v 连边. 然后第x层的u -> 第x+1层的u连边(+oo), S->第一层的1 ...
- BZOJ 1738: [Usaco2005 mar]Ombrophobic Bovines 发抖的牛( floyd + 二分答案 + 最大流 )
一道水题WA了这么多次真是.... 统考终于完 ( 挂 ) 了...可以好好写题了... 先floyd跑出各个点的最短路 , 然后二分答案 m , 再建图. 每个 farm 拆成一个 cow 点和一个 ...
- BZOJ 1305 CQOI2009 dance跳舞 二分答案+最大流
题目大意:给定n个男生和n个女生,一些互相喜欢而一些不.举行几次舞会,每次舞会要配成n对.不能有同样的组合出现.每一个人仅仅能与不喜欢的人跳k次舞,求最多举行几次舞会 将一个人拆成两个点.点1向点2连 ...
- [bzoj3993][SDOI2015]星际战争-二分+最大流
Brief Description 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战.在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai. ...
- HDU3081(KB11-N 二分答案+最大流)
Marriage Match II Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- BZOJ2547 CTSC2002玩具兵(最短路径+二分答案+最大流)
先不考虑只有一个显得有些特殊的天兵. 可以发现超能力的作用实质上是使兵更换职业.每一个兵到达某个位置最少需要更换职业的次数是彼此独立的,因为如果需要某两人互换职业可以使他们各自以当前职业到达需要到的地 ...
随机推荐
- 迭代器模式(java版)
迭代器模式的组成部分 Aggregate(抽象聚合类) 它用于存储和管理元素对象,声明一个createiterator()方法用于创建一个迭代器对象,充当抽象迭代器工厂角色. ConcreteAggr ...
- UVA 10256 The Great Divide(点在多边形内)
The Great Divid [题目链接]The Great Divid [题目类型]点在多边形内 &题解: 蓝书274, 感觉我的代码和刘汝佳的没啥区别,可是我的就是wa,所以贴一发刘汝佳 ...
- html utf-8 中文乱码
刚才用ajax从记事本中读文档的时候,发现在页面上显示是乱码. 页面编码:<meta charset="utf-8"> 搞半天最后发现是记事本编码格式的问题,记事本默认 ...
- java virtual machine launcher Error:Could not create the Java Virtual Machine. Error:A Fatal exception has occurred,Program will exit.
Error:Could not create the Java Virtual Machine. Error:A Fatal exception has occurred,Program will e ...
- 提示“此Flash Player与您的地区不相容,请重新安装Flash”的解决办法
问题原因: 因为Flash相对于HTML5,有着运算效率低.资源占用大.安全性不高等缺点,随着HTML5越来越普及,Adobe已宣布2020年正式停止支持Flash这项技术. 但Adobe公司为了利益 ...
- <1>Cocos Creator安装和启动
学习之间需要了解JavaScritp基本语法和面向对象,详情参考https://blog.csdn.net/jadeshu/article/category/7476938 1.下载Cocos Cre ...
- 设置一个div网页滚动时,使其固定在头部,当页面滚动到距离头部300px时,隐藏该div,另一个div在底部,此时显示;当页面滚动到起始位置时,头部div出现,底部div隐藏
设置一个div网页滚动时,使其固定在头部,当页面滚动到距离头部300px时,隐藏该div,另一个div在底部,此时显示: 当页面滚动到起始位置时,头部div出现,底部div隐藏 前端代码: <! ...
- windows启动项管理
在运行框中输入 msconfig 选择启动栏 会跳转到任务管理器,可以管理启动项,可以看到我的启动项里有nc病毒 ,点击禁用即可.
- 2-1:math库与random库
一.math库: math库是python语言中常用的一个函数库,它包含了一批数学函数,下面我们看一下这个函数库 由于math库中的函数与数学中的函数比较一致,相对比较简单,请同学们自行练习一下: 二 ...
- 设计模式之Visitor(访问者)(转)
Visitor定义 作用于某个对象群中各个对象的操作. 它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作. 在Java中,Visitor模式实际上是分离了collection结构中的 ...