题目:洛谷P3324 [SDOI2015]星际战争

思路:

类似《导弹防御塔》,因为题目保证有解,花费时间小于最终答案时一定无法消灭所有敌人,只要花费时间大于等于最终答案都可以消灭所有敌人,答案满足单调性,考虑二分答案。

二分答案后,转化为判定性问题。当总时间固定,每件武器的总伤害量就确定了。

于是可以按网络流建模:把武器和敌人分成两部分,从源点s向武器连边,容量为该武器可以输出的总伤害量(当前二分到的时间time*该武器的dps);每件武器向可以它攻击到的敌人连边,容量为inf;每个敌人向汇点t连边,容量为该敌人的生命上限。最后只需判断最大流是否等于敌人总生命值。

因为时间是小数,代码中采用double存储。最后要求三位小数,也可以把所有数据都乘10000变成整数以提高精度。

注意我的代码中n、m、a、b与题目中相反。


Code:

#include <bits/stdc++.h>
using namespace std;
const int N=5e5+5,inf=0x3f3f3f3f;
const double eps=1e-4;
double sum,a[N],b[N],val[N];
int n,m,s,t,tot,mp[505][505],d[N];
int Top=1,ver[N],nxt[N],head[N];
inline void add(int u,int v,double w){
ver[++Top]=v;val[Top]=w;nxt[Top]=head[u];head[u]=Top;
ver[++Top]=u;val[Top]=0;nxt[Top]=head[v];head[v]=Top;
}
bool bfs(){
for(int i=1;i<=tot;++i) d[i]=0;
queue<int> q;
q.push(s);
d[s]=1;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i;i=nxt[i]){
int v=ver[i];
if(val[i]>eps&&!d[v]){
d[v]=d[u]+1;
if(v==t) return true;
q.push(v);
}
}
}
return false;
}
double dfs(int u,double flow){
if(u==t) return flow;
double left=flow;
for(int i=head[u];i&&left;i=nxt[i]){
int v=ver[i];
if(val[i]>eps&&d[v]==d[u]+1){
double res=dfs(v,min(left,val[i]));
if(!res) d[v]=0;
val[i]-=res;
val[i^1]+=res;
left-=res;
}
}
return flow-left;
}
bool check(double tim){
memset(head,0,sizeof(head));
memset(ver,0,sizeof(ver));
memset(nxt,0,sizeof(nxt));
memset(val,0,sizeof(val));
Top=1;
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
if(mp[i][j]) add(i,n+j,inf);
}
}
for(int i=1;i<=n;++i) add(s,i,tim*a[i]);
for(int i=1;i<=m;++i) add(n+i,t,b[i]);
double res=0;
while(bfs()) {
res+=dfs(s,inf);
}
return fabs(res-sum)<eps;
}
int main(){
scanf("%d%d",&m,&n);
for(int i=1;i<=m;++i) scanf("%lf",&b[i]);
for(int i=1;i<=n;++i) scanf("%lf",&a[i]);
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
scanf("%d",&mp[i][j]);
}
}
tot=n+m;
s=++tot;
t=++tot;
for(int i=1;i<=m;++i) sum+=b[i];
double l=0,r=2e5;
while(r-l>eps){
double mid=(l+r)*0.5;
if(check(mid)) r=mid;
else l=mid;
}
printf("%.3lf",l);
return 0;
}

洛谷P3324 [SDOI2015]星际战争的更多相关文章

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

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

  2. 洛谷$P3324\ [SDOI2015]$星际战争 网络流+二分

    正解:网络流+二分 解题报告: 传送门$QwQ$ 其实我第一反应是费用流来着,,,但是仔细想了下发现我不会实现各个武器之间独立同时?而且攻击是连续的答案可能是小数嘛$QwQ$. 所以显然不是递推就二分 ...

  3. P3324 [SDOI2015]星际战争

    传送门:https://www.luogu.org/problemnew/show/P3324 首先瞅一眼数据范围,发现m, n都很小,所以就可以初步断定这是一道网络流的题. 因为题中说每一个武器只能 ...

  4. BZOJ 3993 Luogu P3324 [SDOI2015]星际战争 (最大流、二分答案)

    字符串终于告一段落了! 题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=3993 (luogu) https://www.l ...

  5. Luogu P3324 [SDOI2015]星际战争

    二分+最大流 首先考虑二分答案 然后可以发现对于已知时间,判断是否可以将所有机器人摧毁可以用网络流 建立源点和汇点,源点向每一个激光武器连一条容量为$time*b[i]$的边,表示该激光武器在$tim ...

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

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

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

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

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

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

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

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

随机推荐

  1. 关于mapreduce 开发环境部署和jar包拷贝问题

    1.mapreduce开发应当在linux里面的eclipse不然容易出现问题. 2.把eclipse拷贝到linux环境中,然后需要拷贝hadoop-eclipse-plugin-2.3.0.jar ...

  2. 使用tomcat脚本开启服务

    参考:https://www.cnblogs.com/fps2tao/p/8488596.html 1.编写tomcat脚本 在/etc/init.d/目录下创建tomcat服务脚本文件 cd  /e ...

  3. Docker(二)安装及常用命令

    1.安装 1.安装虚拟机VMWare 链接:https://pan.baidu.com/s/1Xl7ENUm2gapPOFs-iXHpRQ 提取码:eubm 2.下载centos,我下的是这个版本的 ...

  4. 用canvas 画出圆形图片

    /** * 把图片处理成圆形,如果不是正方形就按最小边一半为半径处理 * @param {object} imgObj 图片(img)对象 * @param {number} imgType 设置生成 ...

  5. 关于python的列表操作(二):排序,统计

    # 列表操作 num_list = [2, 5, 8, 6, 7, 9, 5, 7] # 升序 num_list.sort() print(num_list) # 降序 num_list.sort(r ...

  6. python基础--字符编码以及文件操作

    字符编码: 1.运行程序的三个核心硬件:cpu.内存.硬盘 任何一个程序要是想要运算,肯定是先从硬盘加载到当前的内存中,然后cpu根据指定的指令去执行操作 2.python解释器运行一个py文件的步骤 ...

  7. Lua报unexpected symbol near错误

    如果Lua脚本没有错误,那可能是UTF8 BOM的问题

  8. 【洛谷P2907】 【USACO08OPEN】农场周围的道路 水模拟分治

    P2907 [USACO08OPEN]农场周围的道路Roads Around The Farm 题目描述 Farmer John's cows have taken an interest in ex ...

  9. Node.js调试技巧

    1. console.log 跟前端调试相同,通过一步步打印相关变量进行代码调试 2. 使用Node.js内置的调试器 通过node debug xxx.js来进行调试: [root@~/wade/n ...

  10. 关于在eclipse中安装各种插件的问题

    在eclipse中安装php插件的方法 参考转载链接:eclipse 安装php插件 并配置环境 elipse的php插件地址:https://www.eclipse.org/pdt/ 以下可能会用到 ...