你以为我拉了嘿嘿其实我真的拉了

· · 题解

题解 P4209。

以来就给我整不会了。怎么处理平方?怎么控制参与总学生最多?其中一定又有什么我不知道的奇技淫巧。

一切尽在连边。

那么问题到这里就算处理完了。直接上费用流即可。

不知道我的代码遭遇了哪家宇宙射线的侵蚀,Dinic 死活过不去,换成 EK 就过了。同学们如果发现自己的 Dinic 过不了也可以试试换 EK。

#define int long long
namespace XSC062 {
using namespace fastIO;
const int maxn = 405;
const int inf = 1e18;
const int maxm = 5e5 + 5;
struct _ {
    int v, c, w, n;
    _() {}
    _(int v1, int c1, int w1, int n1) {
        v = v1, c = c1, w = w1, n = n1;
    }
};
_ u[maxm];
bool inq[maxn];
int n, m, k, x, res;
int gs, gt, tot = 1;
int c[maxn], f[maxn];
int h[maxn], dis[maxn];
int fl[maxn], pre[maxn];
inline int min(int x, int y) {
    return x < y ? x : y;
}
inline bool SPFA(int s, int n) {
    std::queue<int> q;
    std::fill(dis + 1, dis + n + 1, inf);
    q.push(s), dis[s] = 0, inq[s] = 1;
    pre[s] = inf, pre[gt] = 0, fl[s] = inf;
    while (!q.empty()) {
        int f = q.front();
        q.pop(), inq[f] = 0;
        for (int i = h[f]; i; i = u[i].n) {
            if (u[i].c == 0)
                continue;
            int v = u[i].v, w = u[i].w;
            if (dis[v] > dis[f] + w) {
                pre[v] = i ^ 1;
                dis[v] = dis[f] + w;
                fl[v] = min(fl[f], u[i].c);
                if (!inq[v])
                    inq[v] = 1, q.push(v);
            }
        }
    }
    return pre[gt];
}
inline void SSP(int s, int n) {
    int p, mn, d;
    while (SPFA(s, n)) {
        mn = fl[gt], d = 0;
        for (p = gt; p != s; p = u[pre[p]].v) {
            u[pre[p]].c += mn;
            u[pre[p] ^ 1].c -= mn;
            d += u[pre[p] ^ 1].w;
        }
        res += mn * d;
    }
    return;
}
inline void add(int x, int y, int c, int w) {
    u[++tot] = _(y, c, w, h[x]);
    h[x] = tot;
    return;
}
inline void readx(int &x) {
    char ch = nec();
    while (ch != '0' && ch != '1')
        ch = nec();
    x = ch - '0';
    return;
}
int main() {
    read(n), read(m), read(k);
    gs = n + m + 1, gt = gs + 1;
    for (int i = 1; i <= m; ++i) {
        read(c[i]);
        for (int j = 0; j < n; ++j) {
            add(i + n, gt, 1,
                    (2 * j + 1) * c[i]);
            add(gt, i + n, 0,
                    -(2 * j + 1) * c[i]);
        }
    }
    for (int i = 1; i <= m; ++i)
        read(f[i]);
    for (int i = 1; i <= n; ++i) {
        add(gs, i, k, 0);
        add(i, gs, 0, 0);
        add(i, gt, k - 1, 0);
        add(gt, i, 0, 0);
        for (int j = 1; j <= m; ++j) {
            readx(x);
            if (x == 1) {
                add(i, j + n, 1, -f[j]); // 负代价
                add(j + n, i, 0, f[j]);
            }
        }
    }
    SSP(gs, gt);
    print(res, '\n');
    return 0;
}
} // namespace XSC062
#undef int