\(\color{red}{Link}\)

\(\text{Solution:}\)

观察到,如果一个时间\(T\)可以完成任务,则\(T+1\)这个时间也可以完成任务。

于是我们可以二分。

为了避免浮点数,我们可以让时间和血量都乘以\(1000.\)注意攻击力不需要增大,因为时间已经扩大了。

考虑如何网络流建模:

首先,我们把问题转化为\(T\)时间能不能解决。于是,我们可以从源点向激光器连一条容量为攻击力乘以时间的边,每个激光器再向机器人连一条容量无限的边,每一个机器人再向汇点连一条容量为血量的边。

于是,我们跑出最大流,并看看机器人的血量是不是流满了。如果流满了则说明时间\(T\)可行,否则不可行。

根据二分性二分即可。注意清空和\(\text{long long.}\)

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=50000;
const int inf=2147483647;
int n,m,a[MAXN],b[MAXN];
int tot=1,head[MAXN],S,T;
int dep[MAXN],cur[MAXN];
int A[110][110];
struct edge{
int nxt,to,flow;
}e[MAXN];
inline void add(int x,int y,int w){
e[++tot].to=y;e[tot].nxt=head[x];
e[tot].flow=w;head[x]=tot;
e[++tot].to=x;e[tot].nxt=head[y];
e[tot].flow=0;head[y]=tot;
}
bool bfs(int s,int t){
memset(dep,0,sizeof(dep));
queue<int>q;q.push(s);
dep[s]=1;cur[s]=head[s];
while(!q.empty()){
s=q.front();q.pop();
for(int i=head[s];i;i=e[i].nxt){
int j=e[i].to;
if(!dep[j]&&e[i].flow){
dep[j]=dep[s]+1;
cur[j]=head[j];
if(j==t)return true;
q.push(j);
}
}
}
return false;
}
int dfs(int s,int flow,int t){
if(s==t||flow<=0)return flow;
int rest=flow;
for(int i=cur[s];i;i=e[i].nxt){
int j=e[i].to;
if(dep[j]==dep[s]+1&&e[i].flow){
int tmp=dfs(j,min(e[i].flow,rest),t);
if(tmp<=0)dep[j]=0;
rest-=tmp;e[i].flow-=tmp;e[i^1].flow+=tmp;
if(rest<=0)break;
}
}
return flow-rest;
}
int dinic(int s,int t){
int ans=0;
for(;bfs(s,t);)ans+=dfs(s,inf,t);
return ans;
}
bool check(int t){
S=0,T=n+m+1;
tot=1;
int sum=0;
for(int i=1;i<=m;++i)add(S,i,b[i]*t);
for(int i=1;i<=n;++i)add(i+m,T,a[i]),sum+=a[i];
for(int i=1;i<=m;++i){
for(int j=1;j<=n;++j){
if(A[i][j])add(i,j+m,inf);
}
}
int ans=dinic(S,T);
for(int i=0;i<=tot;i++)
e[i].flow=e[i].nxt=e[i].to=0;
for(int i=0;i<=T;i++)
dep[i]=cur[i]=head[i]=0;
if(ans!=sum)return false;
return true;
}
signed main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;++i)scanf("%lld",&a[i]),a[i]*=1000;
for(int i=1;i<=m;++i)scanf("%lld",&b[i]),b[i];
for(int i=1;i<=m;++i)
for(int j=1;j<=n;++j)
scanf("%lld",&A[i][j]);
int l=1,r=1000000000;
while(l+1<r){
int mid=l+r>>1;
if(check(mid))r=mid;
else l=mid;
}
printf("%.6lf\n",r*1.0/1000);
return 0;
}

【题解】[SDOI2015]星际战争的更多相关文章

  1. 3993: [SDOI2015]星际战争

    3993: [SDOI2015]星际战争 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 1244  Solved: ...

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

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

  3. bzoj3993: [SDOI2015]星际战争(网络流)

    3993: [SDOI2015]星际战争 题目:传送门 题解: 洛谷AC了,但是因为bzoj的spj有问题所以暂时没A 一道老题目了,二分时间然后网络流判断. 每次st-->武器连时间*攻击力 ...

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

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

  5. BZOJ_3993_[SDOI2015]星际战争_二分+网络流

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

  6. bzoj千题计划131:bzoj3993: [SDOI2015]星际战争

    http://www.lydsy.com/JudgeOnline/problem.php?id=3993 二分答案 源点向武器连 mid*攻击力的边 机器人向汇点连 防御力 的边 武器i能攻击机器人j ...

  7. 洛谷P3324 [SDOI2015]星际战争

    题目:洛谷P3324 [SDOI2015]星际战争 思路: 类似<导弹防御塔>,因为题目保证有解,花费时间小于最终答案时一定无法消灭所有敌人,只要花费时间大于等于最终答案都可以消灭所有敌人 ...

  8. 洛谷P3324 [SDOI2015]星际战争 题解

    题目链接: https://www.luogu.org/problemnew/show/P3324 分析: 因为本题的时间点较多,不能枚举,但发现有单调性,于是二分答案,二分使用的时间TTT 每个攻击 ...

  9. 【BZOJ】3993: [SDOI2015]星际战争

    题意 \(m\)个人\(n\)个物品,第\(i\)个物品生命值为\(A_i\),第\(i\)个人每秒可以减少一个物品\(B_i\)的生命值,给出一个\(m \times n\)的矩阵,如果\(i\)行 ...

随机推荐

  1. Sql 注入----学习笔记2

    转载自:http://blog.51cto.com/quiterr/1699964 sql注入 sql注入98年第一次出现在<phrack>54期上. 注入攻击有两个关键条件,第一是用户能 ...

  2. checkbox手动样式改变

    .image_input_checkbox{ width:18px; height:18px; display: inline-block; vertical-align: middle; -webk ...

  3. 深入了解Netty【八】TCP拆包、粘包和解决方案

    1.TCP协议传输过程 TCP协议是面向流的协议,是流式的,没有业务上的分段,只会根据当前套接字缓冲区的情况进行拆包或者粘包: 发送端的字节流都会先传入缓冲区,再通过网络传入到接收端的缓冲区中,最终由 ...

  4. [第二届全国中学生网络安全竞赛]bypass

    前几天拿到了线下赛的源码,做做看.这道主要是命令执行的黑名单绕过 先看看给出的代码: <?php highlight_file(__FILE__); error_reporting(0); $b ...

  5. C++类重载函数的function和bind使用

    在没有C++11的std::function和std::bind之前,我们使用函数指针的方式是五花八门,结构很繁琐难懂.C++11中提供了std::function和std::bind统一了可调用对象 ...

  6. CentOS 7常用命令

    常用命令 文件与目录操作 命令 解析 cd /home 进入 ‘/home’ 目录 cd .. 返回上一级目录 cd ../.. 返回上两级目录 cd - 返回上次所在目录 cp file1 file ...

  7. fake_useragent.errors.FakeUserAgentError: Maximum amount of retries reached解决方法!

    UserAgent 就是用户代理,又叫报头,是一串字符串,相当于浏览器的身份证号,在利用爬虫爬取网站数据时,频繁更换它可以避免触发相应的反爬机制. fake-useragent对频繁更换UserAge ...

  8. mysql 5.7密码策略和安装密码校验插件validate_password

    当执行sql:SHOW VARIABLES LIKE 'validate_password%';提示empty,说明没有安装密码插件 1.查看当前mysql安装的插件信息 mysql> show ...

  9. [Liunx]apt-get安装软件:依赖冲突问题及解决

    正常使用apt-get install安装出现依赖冲突问题: 大概是这样: ga@ubuntu:$ sudo apt-get install gcc-5-base:i386 正在读取软件包列表... ...

  10. [LeetCode]69. x 的平方根(数学,二分)

    题目 https://leetcode-cn.com/problems/sqrtx 题解 方法一:牛顿迭代法 按点斜式求出直线方程(即过点Xn,f(Xn)),然后求出直线与x轴交点,即为Xn+1: 求 ...