QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#617731#5114. Cells Coloringmhw#TL 0ms3728kbC++203.8kb2024-10-06 16:48:112024-10-06 16:48:12

Judging History

你现在查看的是最新测评结果

  • [2024-10-06 16:48:12]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:3728kb
  • [2024-10-06 16:48:11]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
const i64 inf = 2e18;
struct MinCostFlow {
    using i64 = long long;
    using PII = pair<i64, int>;
    const i64 INF = numeric_limits<i64>::max();
    struct Edge {
        int v, c, f;
        Edge(int v, int c, int f) : v(v), c(c), f(f) {}
    };
    const int n;
    vector<Edge> e;
    vector<vector<int>> g;
    vector<i64> h, dis;
    vector<int> pre;
    MinCostFlow(int n) : n(n), g(n) {}
    void add(int u, int v, int c, int f) {
        g[u].push_back(e.size());
        e.emplace_back(v, c, f);
        g[v].push_back(e.size());
        e.emplace_back(u, 0, -f);
    }
    bool dijstra(int s, int t) {
        dis.assign(n, INF);
        pre.assign(n, -1);
        priority_queue<PII, vector<PII>, greater<PII>> que;
        dis[s] = 0;
        que.emplace(0, s);
        while(!que.empty()) {
            auto [d, u] = que.top();
            que.pop();
            if (dis[u] < d) continue;
            for (auto i : g[u])
            {
                auto [v, c, f] = e[i];
                if (c > 0 && dis[v] > d + h[u] - h[v] + f)
                {
                    dis[v] = d + h[u] - h[v] + f;
                    pre[v] = i;
                    que.emplace(dis[v], v);
                }
            }
        }
        return dis[t] != INF;
    }
    pair<int, i64> flow(int s, int t)
    {
        int flow = 0;
        i64 cost = 0;
        h.assign(n, 0);
        while (dijstra(s, t))
        {
            for (int i = 0; i < n; i++) h[i] += dis[i];
            int aug = numeric_limits<int>::max();
            for (int i = t; i != s; i = e[pre[i] ^ 1].v) aug = min(aug, e[pre[i]].c);
            for (int i = t; i != s; i = e[pre[i] ^ 1].v)
            {
                e[pre[i]].c -= aug;
                e[pre[i] ^ 1].c += aug;
            }
            flow += aug;
            cost += i64(aug) * h[t];
        }
        return {flow, cost};
    } 
};
void solve() {
    i64 ans = 2e18;
    int n, m, c, d, sum = 0;
    cin >> n >> m >> c >> d;
    vector<string> s(n);
    for (int i = 0; i < n; i++) {
        cin >> s[i];
    }
    vector<int> sn(n + 1), sm(m + 1);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (s[i][j] == '.') {
                sn[i + 1]++;
                sm[j + 1]++;
                sum++;
            }
        }
    }
    auto cal = [&](int x) -> i64 {
        int s = 0, t = n + m + 2;
        MinCostFlow cf(n + m + x + 3);
        for (int i = 1; i <= n; i++) {
            cf.add(0, i, sn[i], 0);
            cf.add(i, n + m + 1, sum, d);
        }
        for (int i = 1; i <= m; i++) {
            cf.add(n + i, n + m + 2, sm[i], 0);
            cf.add(n + m + 1, n + i, sum, 0);
        }
        for (int i = 1; i <= x; i++) {
            for (int j = 1; j <= n; j++) {
                cf.add(j, n + m + 2 + i, 1, 0);
            }
            for (int j = 1; j <= m; j++) {
                cf.add(n + m + 2 + i, n + j, 1, 0);
            }
        }
        auto ans = cf.flow(s, t);
        if (ans.first < sum) return inf;
        return ans.second + x * c;
    };
    int l = 1, r = sum;
    i64 lans, rans;
    while (l < r) {
        int lmid = l + (r - l) / 3;
        int rmid = r - (r - l) / 3;
        lans = cal(lmid), rans = cal(rmid);
        ans = min(lans, ans);
        ans = min(rans, ans);
        // 求凹函数的极小值
        if (lans <= rans) r = rmid - 1;
        else l = lmid + 1;

        // 求凸函数的极大值
        if (lans >= rans) l = lmid + 1;
        else r = rmid - 1;
    }
    cout << ans << '\n';
}
signed main(){
    // ios::sync_with_stdio(0); cin.tie(0), cout.tie(0);
    int T = 1; 
    // cin >> T;
    while (T--) solve();
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3728kb

input:

3 4 2 1
.***
*..*
**..

output:

4

result:

ok 1 number(s): "4"

Test #2:

score: 0
Accepted
time: 0ms
memory: 3512kb

input:

3 4 1 2
.***
*..*
**..

output:

2

result:

ok 1 number(s): "2"

Test #3:

score: -100
Time Limit Exceeded

input:

250 250 965680874 9042302
..**.*****..**..**.*****..***..***.**......*.***.*...***.*....*.**.*.**.*.*.****...*.******.***.************....**.*..*..***.*******.*.***.*..**..****.**.*.*..***.****..**.....***.....*.****...*...*.***..****..**.*.*******..*.*******.*.*.*.****.*.***
....**.*******.*.******...

output:


result: