1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
| #include <iostream>
#include <cstdio>
using namespace std;
const int INF = 1<<30;
typedef long long LL;
int getint() {
int r = 0, k = 1; char c = getchar();
for (; '0' > c || c > '9'; c = getchar()) if (c == '-') k = -1;
for (; '0' <= c && c <= '9'; c = getchar()) r = r * 10 - '0' + c;
return r * k;
}
int n, m, S, T;
const double eps = 0.000001;
double cmp(double a, double b) {
if (-eps <= a - b && a-b <= eps) return true;
return false;
}
const int maxedge = 90005;
const int maxnode = 250;
struct MaxFlowSolver {
int S, T;
struct edge_type {
int to, next;
double r;
} edge[maxedge];
int h[maxnode], cur[maxnode], dis[maxnode], cnte, L, R;
void init(int l, int r) {
cnte = 1;
L = l;
R = r;
for (int i = L; i <= R; ++i) h[i] = 0;
S = T = 0;
}
void ins(int u, int v, double w) {
edge[++cnte].to = v;
edge[cnte].next = h[u];
edge[cnte].r = w;
h[u] = cnte;
edge[++cnte].to = u;
edge[cnte].next = h[v];
edge[cnte].r = 0;
h[v] = cnte;
}
int q[maxnode];
bool BFS() {
int head = 0, tail = 1;
q[0] = S;
for (int i = L; i <= R; ++i) dis[i] = -1;
dis[S] = 0;
int now;
while (head < tail) {
now = q[head++];
for (int i = h[now]; i; i = edge[i].next) {
if (dis[edge[i].to] == -1 && !cmp(edge[i].r, 0.0)) {
dis[edge[i].to] = dis[now] + 1;
q[tail++] = edge[i].to;
}
}
}
return dis[T] != -1;
}
double DFS(int now, double a) {
if (now == T || cmp(a, 0.0)) return a;
double f;
double ret = 0;
for (int &i = cur[now]; i; i = edge[i].next) {
if (dis[edge[i].to] != dis[now] + 1) continue;
if ((f = DFS(edge[i].to, min(a, edge[i].r))) > 0) {
a -= f;
ret += f;
edge[i].r -= f;
edge[i^1].r += f;
if (cmp(a, 0.0)) break;
}
}
if (cmp(ret, 0.0)) dis[now] = -1;
return ret;
}
double Dinic(int start, int end) {
S = start; T = end;
double ret = 0;
while (BFS()) {
for (int i = L; i <= R; ++i) cur[i] = h[i];
ret += DFS(S, INF);
}
return ret;
}
} G;
int A[60];
double B[60];
double suma = 0;
int can[60][60];
bool check(double x) {
G.init(S, T);
for (int i = 1; i <= m; ++i) G.ins(S, i+1, x*B[i]);
for (int i =1; i <= m; ++i)
for (int j = 1; j <= n; ++j)
if (can[i][j])
G.ins(i+1, j+1+m, INF);
for (int i = 1; i <= n; ++i) G.ins(i+1+m, T, A[i]);
double f = G.Dinic(S, T);
return cmp(f, suma);
}
int main() {
n = getint();
m = getint();
S = 1; T = n+m+2;
for (int i =1; i <= n; ++i) { A[i] = getint(); suma += A[i]; }
for (int i =1; i <= m; ++i) B[i] = getint();
for (int i =1; i <= m; ++i)
for (int j = 1; j <= n; ++j)
can[i][j] = getint();
double l = 1.0/50000, r = 500000, mid;
for (int i = 0; i < 35; ++i) {
mid = (l + r) / 2;
if (check(mid)) r = mid;
else l = mid;
}
printf("%.8lf", r);
return 0;
}
|