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
| #include <iostream> #include <cstdio> #include <cmath> #include <queue> #include <cstring> #define MAX_N 100 #define EPS 1e-8 #define INF 0x3f3f3f3f #define mid (l+r)/2 using namespace std; typedef double dnt; struct node {int v, nxt; dnt c;} E[MAX_N*MAX_N*5+500]; dnt sum; int n, m, s, t, a[MAX_N+5], b[MAX_N+5], mrk[MAX_N+5][MAX_N+5], pre[MAX_N+5], d[MAX_N+5], cnt; void init() {memset(pre, -1, sizeof(pre)), cnt = 0, s = 0, t = n+m+1;} void insert(int u, int v, dnt c) {E[cnt].v = v, E[cnt].c = c, E[cnt].nxt = pre[u], pre[u] = cnt++;} void build() { init(); for (int i = 1; i <= n; i++) insert(i, t, a[i]), insert(t, i, 0), sum += a[i]; for (int i = 1; i <= m; i++) insert(s, i+n, INF), insert(i+n, s, 0); for (int i = 1; i <= m; i++) for (int j = 1; j <= n; j++) if (mrk[i][j]) insert(i+n, j, INF), insert(j, i+n, 0); } bool BFS() { queue <int> que; memset(d, -1, sizeof(d)); que.push(s), d[s] = 0; while (!que.empty()) { int u = que.front(); que.pop(); for (int i = pre[u]; ~i; i = E[i].nxt) { int v = E[i].v; if (E[i].c <= EPS || ~d[v]) continue; d[v] = d[u]+1; que.push(v); } } return ~d[t]; } dnt DFS(int u, dnt flow) { if (u == t) return flow; dnt ret = 0; for (int i = pre[u]; ~i; i = E[i].nxt) { int v = E[i].v; if (E[i].c <= EPS || d[v] != d[u]+1) continue; dnt tmp = DFS(v, min(flow, E[i].c)); E[i].c -= tmp, E[i^1].c += tmp, ret += tmp, flow -= tmp; if (!flow) break; } if (!ret) d[u] = -1; return ret; } bool chk(dnt tans) { for (int i = 0; i < cnt; i += 2) E[i].c += E[i^1].c, E[i^1].c = 0; for (int i = pre[s]; ~i; i = E[i].nxt) E[i].c = (dnt)b[E[i].v-n]*tans; dnt tot = 0; while (BFS()) tot += DFS(s, INF); return fabs(tot-sum) <= EPS; } dnt bi_search(dnt l, dnt r) { dnt ret = -1; for (int i = 0; i < 100; i++) if (chk(mid)) ret = r = mid; else l = mid; return ret; } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", a+i); 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++) scanf("%d", &mrk[i][j]); build(), printf("%.5lf", bi_search(0, INF)); return 0; }
|