首页 技术 正文
技术 2022年11月19日
0 收藏 704 点赞 5,088 浏览 2083 个字

http://www.lydsy.com/JudgeOnline/problem.php?id=3993

调了好长时间啊

这道题设时间为time,那么对于m个武器从S向这m个点连容量为time*Bi的边,代表能造成的总伤害。

对于每个武器向每个能打到的机器人连容量为无穷的边。

对每个机器人向T连自己的装甲量Ai为容量的边。

又因为每个机器人的装甲必须被打完,所以设机器人到T的边的下界为Ai(上下界相等)。

从T向S连容量无穷大的边,构成无源汇上下界网络流,所以构造附加网络然后二分时间time就可以了。

注意附加网络有一些边是走不通的,所以把那些边删掉也可以

(删掉后和原网络没什么区别啊Σ( ° △ °|||)︴那我还讲这么偏QAQ)。

Dinic模板打残致命伤!!!以后改数组边界的时候注意要看程序中调用数组边界的常量是否也需要改。

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define forU(i, a, b) for (int i = (a), UP = (b); i <= UP; ++i)
#define forD(i, a, b) for (int i = (a), DOWN = (b); i >= DOWN; --i)
using namespace std;inline double fabs(double x) {return x < 0 ? -x : x;}const int N = 55;
const int M = N * N * 2;struct node {
int nxt, to; double c;
node(int _nxt = 0, int _to = 0, double _c = 0) : nxt(_nxt), to(_to), c(_c) {}
} E[M];
int cnt, point[N << 1], cur[N << 1];void ins(int u, int v, double c) {
E[++cnt] = node(point[u], v, c); point[u] = cnt;
E[++cnt] = node(point[v], u, 0); point[v] = cnt;
}bool can[N][N];
int q[N << 1], n, m, S, T, d[N << 1];
double A[N], B[N];bool BFS() {
memset(d, 0, sizeof(int) * (T + 1));
int head = 0, tail = 1, u, v; q[1] = S; d[S] = 1;
while (head != tail) {
u = q[++head];
for (int i = point[u]; i; i = E[i].nxt)
if (fabs(E[i].c) > 1e-12 && !d[v = E[i].to]) {
d[v] = d[u] + 1;
q[++tail] = v;
}
}
return d[T];
}double DFS(int u, double a) {
if (fabs(a) < 1e-12 || u == T) return a;
double f, flow = 0;
for (int &i = cur[u]; i; i = E[i].nxt)
if (d[E[i].to] == d[u] + 1 && fabs(f = DFS(E[i].to, min(a, E[i].c))) > 1e-12) {
a -= f; flow += f; E[i].c -= f; E[i ^ 1].c += f;
if (fabs(a) < 1e-12) break;
}
return flow;
}double Dinic() {
double flow = 0;
while (BFS()) {
memcpy(cur, point, sizeof(int) * (T + 1));
flow += DFS(S, 100000000000000.0);
}
return flow;
}double tot = 0;bool can2(double tim) {
memset(point, 0, sizeof(int) * (T + 1));
cnt = 1;
forU (i, 1, m) {
ins(S, i, tim * B[i]);
forU (j, 1, n)
if (can[i][j])
ins(i, j + m, 100000000000000.0);
}
forU (i, 1, n) ins(i + m, T, A[i]);return fabs(Dinic() - tot) < 1e-5;
}int main() {
scanf("%d%d", &n, &m); S = n + m + 1; T = S + 1;
forU (i, 1, n) scanf("%lf", A + i), tot += A[i];
forU (i, 1, m) scanf("%lf", B + i);
int num;
double left = 0, right = 0, mid;
forU (i, 1, m)
forU (j, 1, n) {
scanf("%d", &num);
can[i][j] = num;
}
forU (i, 1, n) {
double fornow = 0;
forU (j, 1, m)
fornow = max(fornow, B[j]);
right += ceil(A[i] / fornow);
}while (right - left > 1e-5) {
mid = (left + right) / 2.0;
if (can2(mid)) right = mid;
else left = mid;
}printf("%lf\n", left);
return 0;
}
上一篇: Quartz定时任务
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,075
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,551
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,399
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,176
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,811
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,893