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玩具兵(最短路径+二分答案+最大流)
先不考虑只有一个显得有些特殊的天兵. 可以发现超能力的作用实质上是使兵更换职业.每一个兵到达某个位置最少需要更换职业的次数是彼此独立的,因为如果需要某两人互换职业可以使他们各自以当前职业到达需要到的地 ...
随机推荐
- 地图服务报 error #2035
参考:https://blog.csdn.net/iteye_20296/article/details/82395628 现在问题解决了,确实是config.xml里关于这个widget的配置url ...
- 笔记 : Ubuntu部署LNMP环境
一.准备与安装 1. 安装PHP7.1 #添加php源 :~$ sudo add-apt-repository ppa:ondrej/php #更新apt数据,载入php源数据 :~$ sudo ap ...
- notepad去掉空行
选择替换,把查找模式设置为正则表达式,在查找框中自己输入 ^\s+ ,替换框留空,点“全部替换”,即可(先全选).注意:不要复制我的,自己输入,且用英文格式输入.
- 2017高教杯数学建模B 题分析
B题原文 "拍照赚钱"是移动互联网下的一种自助式服务模式.用户下载APP,注册成为APP的会员,然后从APP上领取需要拍照的任务(比如上超市去检查某种商品的上架情况),赚取APP对 ...
- Steam API调试
概览 经过这些年,Steam 已经成长为一款大型应用程序,提供多款调试用单独模块及方法.本文将尽量向您呈现这些模块与方法,帮助您充分利用 Steam 与 Steamworks,减少烦恼. Steam ...
- 【Linux学习七】软件安装
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 一.编译安装1.解压 源码文件是压缩包 要先解压tar -zxvf t ...
- vm无法删除干净老版本,新版本无法安装解决
百度中搜索“Windows Installer Clean UP 简体中文版”来下载安装好 开始程序,打开此软件, 找到vm,点remove 再次安装vm新版本,ok
- 检测FTP服务并开启FTP服务
1. 检测FTP服务是否开启 1.1. 通过查询提供FTP服务的进程是否存在,并未找到任何包含ftp关键字的进程信息,可判断服务未开启. root@lb- ~ # ps -ef | grep ftp ...
- Extjs4前端开发代码规范参考
准则: 一致性, 隔离与统一管理, 螺旋式重构改进, 消除重复, 借鉴现有方案 1. 保证系统实现的一致性,寻求一致性方案, 相同或相似功能尽量用统一模式处理: 2. 尽可能使用隔离技术 ...
- Python: 字典dict: zip()
problem: 怎样在数据字典中执行一些计算操作(比如求最小值.最大值.排序等等)? answer: eg1: 考虑下面的股票名和价格映射字典: prices = {'ACME': 45.23,'A ...