bzoj4819 [Sdoi2017] freshman dance score maximum cost maximum flow planning +

Topic Portal

https://lydsy.com/JudgeOnline/problem.php?id=4819

answer

First it says,
\ [C = \ {FRAC \ SUM \ limits_. 1 = {I}} ^ {n-a'_i \ SUM \ limits_. 1} = {I} ^ n-b'_i \]
to \ (C \) maximum. This is a very common programming model score, then converted to two minutes after
\ [\ \ limits_ {i =
1} ^ n a'_i sum - k \ cdot b'_i \ geq 0 \] so obtained is transformed into weights and maximum choice of solutions to meet each person only once.

Model may be a bipartite graph matching, the cost can be converted to the maximum the maximum flow is completed.


Time complexity is metaphysics, not sure why can too.

Adjust the minimum cost half the maximum flow suddenly thought should maintain maximum cost maximum flow.

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back

template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;}

typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;

template<typename I> inline void read(I &x) {
    int f = 0, c;
    while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    x = c & 15;
    while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    f ? x = -x : 0;
}

const int NN = 100 + 7;
const int N = 100 * 100 + 7;
const int M = 100 * 100 + 200 + 7;
const int INF = 0x3f3f3f3f;

int n, nod, S, T, hd, tl;
int a[NN][NN], b[NN][NN], id[NN][NN], q[N], inq[N], cur[N], vis[N];
double dis[N];

struct Edge { int to, ne, f; double w; } g[M << 1]; int head[N], tot = 1;
inline void addedge(int x, int y, int z, double w) { g[++tot].to = y, g[tot].f = z, g[tot].w = w, g[tot].ne = head[x], head[x] = tot; }
inline void adde(int x, int y, int f, double w) { addedge(x, y, f, w), addedge(y, x, 0, -w); }

inline void qpush(int x) { ++tl; tl == N ? tl = 1 : 0; q[tl] = x; }
inline int qhead() { ++hd; hd == N ? hd = 1 : 0; return q[hd]; }
inline bool spfa() {
    for (int i = 1; i <= nod; ++i) dis[i] = -1e9, vis[i] = 0, cur[i] = head[i];
    q[hd = 0, tl = 1] = S, inq[S] = 0, dis[S] = 0;
    while (hd != tl) {
        int x = qhead();
        inq[x] = 0;
        for fec(i, x, y) if (g[i].f && smax(dis[y], dis[x] + g[i].w) && !inq[y]) qpush(y), inq[y] = 1;
    }
    return dis[T] > -1e9;
}
inline int dfs(int x, int a, double &mc) {
    if (x == T || !a) return mc += dis[x] * a, a;
    int f, flow = 0;
    vis[x] = 1;
    for (int &i = cur[x]; i; i = g[i].ne) {
        int y = g[i].to
        if (vis[y] || (dis[y] != dis[x] + g[i].w)) continue;
        if (!(f = dfs(y, std::min(g[i].f, a), mc))) continue;
        g[i].f -= f, g[i ^ 1].f += f;
        flow += f, a -= f;
        if (!a) return flow;
    }
    dis[x] = INF;
    return flow;
}
inline double mcmf() {
    double ans = 0, tmp = 0;
    while (spfa()) tmp = 0, dfs(S, INF, tmp), ans += tmp;
    return ans;
}

inline bool check(double mid) {
    memset(head, 0, sizeof(int) * (nod + 1)), tot = 1;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j) adde(i, j + n, 1, a[i][j] - mid * b[i][j]);
    for (int i = 1; i <= n; ++i) adde(S, i, 1, 0), adde(i + n, T, 1, 0);
    return mcmf() >= 0;
}

inline void work() {
    S = ++nod, T = ++nod;
    double l = 0, r = 1e4 + 7;
    while (r - l  >= 1e-7) {
        double mid = (l + r) / 2;
        if (check(mid)) l = mid;
        else r = mid;
    }
    printf("%.6lf\n", l);
}

inline void init() {
    read(n);
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j) read(a[i][j]), id[i][j] = ++nod;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j) read(b[i][j]);
}

int main() {
#ifdef hzhkk
    freopen("hkk.in", "r", stdin);
#endif
    init();
    work();
    fclose(stdin), fclose(stdout);
    return 0;
}

Guess you like

Origin www.cnblogs.com/hankeke/p/bzoj4819.html