[bzoj3993][SDOI2015]星际战争-二分+最大流
2017-03-21 21:34
417 查看
Brief Description
3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战。在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai。当一个巨型机器人的装甲值减少到0或者以下时,这个巨型机器人就被摧毁了。X军团有M个激光武器,其中第i个激光武器每秒可以削减一个巨型机器人Bi的装甲值。激光武器的攻击是连续的。这种激光武器非常奇怪,一个激光武器只能攻击一些特定的敌人。Y军团看到自己的巨型机器人被X军团一个一个消灭,他们急需下达更多的指令。为了这个目标,Y军团需要知道X军团最少需要用多长时间才能将Y军团的所有巨型机器人摧毁。但是他们不会计算这个问题,因此向你求助。
Algorithm Design
明明是非常水的套路题却卡了很久, 看来是太长时间没有做网络流的题目手生了, 我真的是思博啊, 我这样的人就应该早点滚粗吧Orz
我们考虑直接二分答案, 这样所有武器能输出的最大火力就有了, 按照火力建模, 随便搞搞就有了.
我真是思博啊.
数组开小了...然后不爽一下子开150万就过了Orz
Code
#include <algorithm> #include <cmath> #include <cstdio> #include <queue> const double eps = 1e-9; #define ld long double const int maxn = 110 << 1; const int inf = 0x3f3f3f; struct edge { int to, next; ld cap; edge(int a = 0, int b = 0, ld c = 0) : to(a), next(b), cap(c) {} } e[1500005]; int cnt = 1, n, m, s, t, v; ld L, R; int head[maxn], mi[maxn], A[maxn], B[maxn], tod; ld dist[maxn]; void add_edge(int u, int v, ld c) { e[++cnt] = edge(v, head[u], c); head[u] = cnt; } void add(int u, int v, ld c) { add_edge(u, v, c); add_edge(v, u, 0); } void bfs(int s) { std::fill(dist, dist + v, -1); dist[s] = 0; std::queue<int> q; q.push(s); while (!q.empty()) { int u = q.front(); q.pop(); for (int i = head[u]; i; i = e[i].next) { if (dist[e[i].to] == -1 && e[i].cap > eps) { dist[e[i].to] = dist[u] + e[i].cap; q.push(e[i].to); } } } } ld dfs(int s, int t, ld flow) { if (s == t) return flow; for (int i = head[s]; i; i = e[i].next) { // printf("%.2f ", e[i].cap); if (e[i].cap > eps && dist[e[i].to] > dist[s]) { ld d = dfs(e[i].to, t, std::min(e[i].cap, flow)); if (d > eps) { e[i].cap -= d; e[i ^ 1].cap += d; return d; } } } return 0; } ld dinic(int s, int t) { ld flow = 0; while (1) { bfs(s); if (dist[t] == -1) return flow; ld d; while ((d = dfs(s, t, inf))) flow += d; } return flow; } bool check(ld mid) { for (int i = 2; i <= cnt; i += 2) e[i].cap += e[i ^ 1].cap, e[i ^ 1].cap = 0; for (int i = head[s]; i; i = e[i].next) e[i].cap = mid * B[e[i].to]; ld flow = dinic(s, t); return std::fabs(flow - (ld)tod) <= eps; } int main() { #ifndef ONLINE_JUDGE freopen("input", "r", stdin); #endif scanf("%d %d", &n, &m); s = 0, t = n + m + 1, v = t + 1, L = 0, R = 0; for (int i = 1; i <= n; i++) { scanf("%d", &A[i]); mi[i] = inf; } for (int i = 1; i <= m; i++) scanf("%d", &B[i]); for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { int x; scanf("%d", &x); if (x == 1) { add(i, j + m, inf); mi[j] = std::min(mi[j], B[i]); } } add(0, i, inf); } for (int i = 1; i <= n; i++) { R += A[i] / mi[i]; add(i + m, t, A[i]); tod += A[i]; } // printf("%d\n", tod); R = 5e6; while (R - L > eps) { ld mid = (L + R) / 2; if (check(mid)) R = mid; else L = mid; } printf("%.7Lf", (L + R) / 2); }
相关文章推荐
- 【BZOJ3993】星际战争(SDOI2015)-二分答案+最大流
- 【二分答案】【最大流】bzoj3993 [Sdoi2015]星际战争
- BZOJ 3993 Sdoi2015 星际战争 二分答案+最大流
- bzoj 3993: [SDOI2015]星际战争 (二分+最大流)
- [SDOI2015][bzoj3993] 星际战争 [二分+最大流]
- [BZOJ3993]-[SDOI2015]星际战争-二分答案+最大流
- 【bzoj3993】[SDOI2015]星际战争 二分+最大流
- 【bzoj3993】[SDOI2015]星际战争 二分+最大流
- 【BZOJ3993】[SDOI2015]星际战争 二分+最大流
- bzoj 3993: [SDOI2015]星际战争 二分答案+最大流
- [BZOJ3993][SDOI2015]星际战争(二分答案+最大流)
- [BZOJ3993][SDOI2015]星际战争(二分+最大流)
- BZOJ 3993 [SDOI2015]星际战争 二分+最大流
- 网络流(二分):BZOJ 3993: [SDOI2015]星际战争
- bzoj3993 [SDOI2015]星际战争 二分答案+网络流检验
- 【BZOJ】3993 [SDOI2015]星际战争 二分+网络流
- BZOJ 3993: [SDOI2015]星际战争 [二分答案 二分图]
- BZOJ 3993 [SDOI2015]星际战争 | 网络流 二分答案
- BZOJ 3993: [SDOI2015]星际战争 二分+网络流
- bzoj 3993: [SDOI2015]星际战争 二分答案&网络流