首先我们可以二分答案。

假设当前二分出来的答案是 $Ans$ ,那么我们考虑用网络流检验:

设武器为 $X$,第 $i$ 个武器的攻击力为 $B_i$;

设机器人为 $Y$,第 $i$ 个机器人的装甲为 $A_i$;

设 $Map[i][j]$ 表示第 $i$ 个机器人是否能攻击第 $j$ 号机器人。

设源为 $S$,汇为 $T$,现在考虑连边:

  • $S\rightarrow X_i$,容量为 $Ans * B_i$;
  • $Y_i\rightarrow T$,容量为 $A_i$;
  • $\forall (i,j),Map[i][j]=1:X_i\rightarrow Y_j$,容量为 $\infty$

然后跑网络流,假设最大流为 $M$,那么看是否有:$M=\sum A_i$。

如果是,那么说明当前答案是满足的,更新上界,否则更新下界。

毕竟 Gromah 太弱,只会做水题。

 #include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long double LD;
#define N 50 + 5
#define M 100000 + 5
#define INF 1e9
#define eps 1e-9 int n, m, S, T, sum, tot;
int A[N], B[N];
int Head[N << ], q[N << ], Dfn[N << ];
bool Map[N][N];
LD l = 0.0, r; struct Edge
{
int next, node;
LD flow;
}h[M]; inline void addedge(int u, int v, LD fl)
{
h[++ tot].next = Head[u], Head[u] = tot;
h[tot].node = v, h[tot].flow = fl;
h[++ tot].next = Head[v], Head[v] = tot;
h[tot].node = u, h[tot].flow = ;
} inline bool BFS()
{
for (int i = S; i <= T; i ++)
Dfn[i] = ;
int l = , r = ;
q[] = S, Dfn[S] = ;
while (l <= r)
{
int z = q[l ++];
for (int i = Head[z]; i; i = h[i].next)
{
int d = h[i].node;
LD p = h[i].flow;
if (p < eps || Dfn[d]) continue ;
Dfn[d] = Dfn[z] + ;
q[++ r] = d;
if (d == T) return ;
}
}
return ;
} inline LD dinic(int z, LD inflow)
{
if (z == T || inflow < eps) return inflow;
LD ret = inflow, flow;
for (int i = Head[z]; i; i = h[i].next)
{
int d = h[i].node;
LD p = h[i].flow;
if (Dfn[d] != Dfn[z] + ) continue ;
flow = dinic(d, min(p, ret));
ret -= flow;
h[i].flow -= flow, h[i ^ ].flow += flow;
if (ret < eps) return inflow;
}
if (fabs(inflow - ret) < eps) Dfn[z] = -;
return inflow - ret;
} inline bool Judge(LD k)
{
tot = ;
for (int i = S; i <= T; i ++)
Head[i] = ;
for (int i = ; i <= m; i ++)
addedge(S, i, k * B[i]);
for (int i = ; i <= n; i ++)
addedge(i + m, T, A[i]);
for (int i = ; i <= m; i ++)
for (int j = ; j <= n; j ++)
if (Map[i][j]) addedge(i, j + m, INF);
LD res = 0.0;
while (BFS())
res += dinic(S, INF);
return fabs(res - sum) < eps;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("3993.in", "r", stdin);
freopen("3993.out", "w", stdout);
#endif scanf("%d%d", &n, &m);
S = , T = n + m + ;
for (int i = ; i <= n; i ++)
{
scanf("%d", A + i);
r += A[i];
sum += A[i];
}
for (int i = ; i <= m; i ++)
scanf("%d", B + i);
for (int i = ; i <= m; i ++)
for (int j = ; j <= n; j ++)
scanf("%d", Map[i] + j);
while (l + 1e- < r)
{
LD mid = (l + r) / ;
if (Judge(mid)) r = mid;
else l = mid;
}
printf("%.4lf\n", (double) l); #ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return ;
}

3993_Gromah

BZOJ 3993 [SDOI 2015] 星际战争 解题报告的更多相关文章

  1. BZOJ 3992 [SDOI 2015] 序列统计 解题报告

    这个题最暴力的搞法就是这样的: 设 $Dp[i][j]$ 为前 $i$ 个数乘积为 $j$ 的方案数. 转移的话就不多说了哈... 当前复杂度 $O(nm^2)$ 注意到,$M$ 是个质数,就说明 $ ...

  2. [SDOI 2015] 星际战争

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=3993 [算法] 首先发现问题具有单调性 , 不妨二分答案mid 考虑网络流 : 将源 ...

  3. BZOJ 4004 [JLOI 2015] 装备购买 解题报告

    哎这个题 WA 了无数遍...果然人太弱... 首先我们把这些装备按照花费从小到大排序,然后依次考虑是否能买这个装备. 至于这样为什么是对的,好像有一个叫拟阵的东西可以证明,然而我不会.TATQAQ ...

  4. [BZOJ 3992] [SDOI 2015] 序列统计(DP+原根+NTT)

    [BZOJ 3992] [SDOI 2015] 序列统计(DP+原根+NTT) 题面 小C有一个集合S,里面的元素都是小于质数M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数 ...

  5. BZOJ 3990 [SDOI 2015] 排序 解题报告

    这个题哎呀...细节超级多... 首先,我猜了一个结论.如果有一种排序方案是可行的,假设这个方案是 $S$ . 那么我们把 $S$ 给任意重新排列之后,也必然可以构造出一组合法方案来. 于是我们就可以 ...

  6. NOI 2015 滞后赛解题报告

    报同步赛的时候出了些意外.于是仅仅能做一做"滞后赛"了2333 DAY1 T1离线+离散化搞,对于相等的部分直接并查集,不等部分查看是否在同一并查集中就可以,code: #incl ...

  7. 洛谷 P2317 [HNOI2005]星际贸易 解题报告

    P2317 [HNOI2005]星际贸易 题目描述 输入输出格式 输入格式: 输出格式: 如果可以找到这样的方案,那么输出文件output.txt中包含两个整数X和Y.X表示贸易额,Y表示净利润并且两 ...

  8. 洛谷 P2245 星际导航 解题报告

    P2245 星际导航 题目描述 sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好.为了方便起见,我们可以认为宇宙是一张有N 个顶点和M 条边的带权无向 ...

  9. 洛谷 P2469 [SDOI2010]星际竞速 解题报告

    题目描述 10年一度的银河系赛车大赛又要开始了.作为全银河最盛大的活动之一,夺得这个项目的冠军无疑是很多人的梦想,来自杰森座α星的悠悠也是其中之一. 赛车大赛的赛场由N颗行星和M条双向星际航路构成,其 ...

随机推荐

  1. [转载]传智播客_SQL入门

    原文地址:传智播客_SQL入门作者:happylonger SQL * 数据定义语言 DDL * 数据操作语言 DML * 查询和更新指令构成了 SQL 的 DML 部分:  * SELECT - 从 ...

  2. Android开发之BroadcastReceiver

    BroadcastReceiver:广播接收者.用来接收系统或应用中的广播. 在Android系统中,广播体现在方方面面,例如当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能: ...

  3. ###《Effective STL》--Chapter3

    点击查看Evernote原文. #@author: gr #@date: 2014-09-13 #@email: forgerui@gmail.com Chapter3 关联容器 Topic 22: ...

  4. Markdown 生成目录

    <link rel="stylesheet" href="http://yandex.st/highlightjs/6.2/styles/googlecode.mi ...

  5. UIMenuController/UIPasteboard(2) UITableView上实用剪贴板

    在UITableView上实用剪贴板有两种方法: 一.在tableView的代理方法中直接有三个有关剪贴板的方法. //某行是否允许show菜单 -(BOOL)tableView:(UITableVi ...

  6. iOS 安全:UIWebView访问Https站点防止中间人攻击

    尽管Https协议能够提供数据的加密.身份的认证等安全服务,但并不是没有漏洞.HTTPS协议安全隐患的存在可能使用户受到各种极具破坏力的网络攻击.其中中间人攻击(Man In The Middle, ...

  7. Java多线程的安全问题

    /*多线程的安全问题1.为什么会出现安全问题?因为程序在运行时,会出现一个线程在判断条件满足后,具备了执行资格,但没有运行代码后一个线程也判断了条件,也具备了执行资格,后一个线程运行了代码,但这时候, ...

  8. [转]怎样在cmd(命令提示符)下进行复制粘贴操作

    原文链接:http://jingyan.baidu.com/article/93f9803fd3a4dde0e46f55f5.html cmd下复制粘贴的快捷操作方式 工具/原料 系统cmd 步骤/方 ...

  9. 第36条:坚持使用Override注解

    @Override 注解只能用在方法声明中,表示被注解的方法声明覆盖了超类型中的一个声明. @Target(ElementType.METHOD) @Retention(RetentionPolicy ...

  10. 两种Ajax方法

    两种Ajax方法 Ajax是一种用于快速创建动态网页的技术,他通过在后台与服务器进行少量的数据交换,可以实现网页的异步更新,不需要像传统网页那样重新加载页面也可以做到对网页的某部分作出更新,现在这项技 ...