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
| #include <bits/stdc++.h> #define rep(i, x, y) for (int i = x; i <= y; i++) using namespace std;
const int N = 2e4 + 5, inf = 1e9; const double eps = 1e-9; int n, a[105][105], b[105][105], S, T; int to[N], fr[N], lnk[N], cnt, nxt[N], cap[N], pre[N], rest[N]; bool inq[N]; double val[N], dis[N], ans; queue<int> q;
void add(int x, int y, int c, double v) { ++cnt; to[cnt] = y, fr[cnt] = x, nxt[cnt] = lnk[x], lnk[x] = cnt, cap[cnt] = c, val[cnt] = v; }
bool spfa(int S, int T, int &flow, double &cost) { rep(i, S, T) dis[i] = -1e18, inq[i] = pre[i] = 0; inq[S] = 1, rest[S] = inf, pre[S] = 0, dis[S] = 0; q.push(S); while (q.size()) { int x = q.front(); q.pop(); inq[x] = 0; for (int i = lnk[x]; i; i = nxt[i]) { int y = to[i]; if (cap[i] > 0 && dis[y] < dis[x] + val[i]) { dis[y] = dis[x] + val[i]; pre[y] = i; rest[y] = min(rest[x], cap[i]); if (!inq[y]) { inq[y] = 1, q.push(y); } } } } if (dis[T] == -1e18) return 0; flow += rest[T]; cost += dis[T] * rest[T]; int x = T; while (x != S) { cap[pre[x]] -= rest[T], cap[pre[x] ^ 1] += rest[T]; x = fr[pre[x]]; } return 1; }
bool chk(double mid) { cnt = 1; memset(lnk, 0, sizeof(lnk)); rep(i, 1, n) { add(S, i, 1, 0), add(i, S, 0, 0); add(i + n, T, 1, 0), add(T, i + n, 0, 0); } rep(i, 1, n) { rep(j, 1, n) { double v = a[i][j] - b[i][j] * mid; add(i, j + n, 1, v); add(j + n, i, 0, -v); } } int flow = 0; double cost = 0; while (spfa(S, T, flow, cost)); return cost >= 0; }
int main() { cin >> n; S = 0, T = 2 * n + 1; rep(i, 1, n) rep(j, 1, n) cin >> a[i][j]; rep(i, 1, n) rep(j, 1, n) cin >> b[i][j]; double l = 0, r = 1e9; while (r - l > eps) { double mid = (l + r) / 2.0; if (chk(mid)) ans = mid, l = mid; else r = mid; } printf("%.6lf\n", ans); return 0; }
|