Description
3333
年,在银河系的某星球上, X军团和Y军团正在激烈地作战。在战斗的某一阶段,Y军团一共派遣了
N
个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为
Input
第一行,两个整数,
N,M
。
第二行,
N
个整数,
第三行,
M
个整数,
接下来的
M
行,每行
Output
一行,一个实数,表示X军团要摧毁Y军团的所有巨型机器人最少需要的时间。输出结果与标准答案的绝对误差不超过 10−3 即视为正确。
Sample Input
2 2
3 10
4 6
0 1
1 1
Sample Output
1.300000
HINT
对于全部的数据, 1≤N,M≤50,1≤Ai≤105,1≤Bi≤1000 ,输入数据保证X军团一定能摧毁Y军团的所有巨型机器人
Solution
azi只会做傻逼题
二分+最大流
每次二分一个答案
x
,如下重新建图:
S 往每个武器连边,流量为 x×Bi- 每个怪兽往
T
连边,流量为
Ai - 如果武器
i
可以攻击怪兽
j , i 往j 连边,流量为 INF #include<bits/stdc++.h> using namespace std; #define N 1000 #define eps (1e-9) #define INF (1e9) #define rep(i, a, b) for (int i = a; i <= b; i++) #define lb long double inline int read() { int x = 0, flag = 1; char ch = getchar(); while (!isdigit(ch)) { if (!(ch ^ '-')) flag = -1; ch = getchar(); } while (isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar(); return x * flag; } inline void write(int x) { if (!x) { putchar('0'); return; } if (x < 0) putchar('-'), x = -x; char buf[20] = ""; int top = 0; while (x) buf[++top] = x % 10 + '0', x /= 10; while (top) putchar(buf[top--]); } int n, m; int A[N], B[N], sum; struct edge { int v, next; lb c; }e[1000005]; int head[N], tot, S, T; bool Map[N][N]; int dep[N], q[N]; inline void add(int u, int v, lb c) { e[++tot] = edge{ v, head[u], c }; head[u] = tot; e[++tot] = edge{ u, head[v], 0 }; head[v] = tot; } inline bool bfs() { int l = 1, r = 1; memset(dep, 0, sizeof dep); q[r] = S, dep[S] = 1; while (l <= r) { int u = q[l++]; for (int i = head[u]; i; i = e[i].next) { int v = e[i].v; lb c = e[i].c; if (c < eps || dep[v]) continue; dep[v] = dep[u] + 1, q[++r] = v; if (v == T) return 1; } } return 0; } double dfs(int u, lb dis) { if (!(u ^ T) || dis < eps) return dis; for (int i = head[u]; i; i = e[i].next) { int v = e[i].v; lb c = e[i].c; if ((dep[v] ^ dep[u] + 1) || c < eps) continue; lb d = dfs(v, min(dis, c)); if (d < eps) continue; e[i].c -= d, e[i ^ 1].c += d; return d; } return 0.0; } bool check(lb x) { memset(head, 0, sizeof head); tot = 1; rep(i, 1, m) add(S, i, x * B[i]); rep(i, 1, n) add(i + m, T, A[i]); rep(i, 1, m) rep(j, 1, n) if (Map[i][j]) add(i, j + m, INF); lb ans = 0.0; while (bfs()) ans += dfs(S, INF); return fabs(ans - sum) < eps; } int main() { scanf("%d%d", &n, &m); T = n + m + 1; rep(i, 1, n) A[i] = read(), sum += A[i]; rep(i, 1, m) B[i] = read(); rep(i, 1, m) rep(j, 1, n) Map[i][j] = read(); lb l = 0.0, r = sum * 1.0; while (l + 1e-4 < r) { lb mid = (l + r) / 2; if (check(mid)) r = mid; else l = mid; } printf("%.4lf", (double)l); return 0; }
- 每个怪兽往
T
连边,流量为