QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#618410#5114. Cells Coloringrxzfn639TL 557ms5124kbC++234.7kb2024-10-06 21:52:282024-10-06 21:52:29

Judging History

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

  • [2024-10-06 21:52:29]
  • 评测
  • 测评结果:TL
  • 用时:557ms
  • 内存:5124kb
  • [2024-10-06 21:52:28]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
const i64 P = 998244353;
template <typename T> struct PushRelabel {
    const int inf = 0x3f3f3f3f;
    const T INF = 0x3f3f3f3f;
    struct Edge {
        int to, cap, flow, anti;
        Edge(int v = 0, int w = 0, int id = 0) : to(v), cap(w), flow(0), anti(id) {}
    };
    vector<vector<Edge>> e; 
    vector<vector<int>> gap;
    vector<T> ex; // 超额流
    vector<bool> ingap;
    vector<int> h;
    int n, gobalcnt, maxH = 0;
    T maxflow = 0;

    PushRelabel(int n) : n(n), e(n + 1), ex(n + 1), gap(n + 1) {}
    void add(int u, int v, int w) {
        e[u].push_back({v, w, (int)e[v].size()});
        e[v].push_back({u, 0, (int)e[u].size() - 1});
    }
    void PushEdge(int u, Edge &edge) {
        int v = edge.to, d = min(ex[u], edge.cap - edge.flow);
        ex[u] -= d;
        ex[v] += d;
        edge.flow += d;
        e[v][edge.anti].flow -= d;
        if (h[v] != inf && d > 0 && ex[v] == d && !ingap[v]) {
            ++gobalcnt;
            gap[h[v]].push_back(v);
            ingap[v] = 1;
        }
    }
    void PushPoint(int u) {
        for (auto k = e[u].begin(); k != e[u].end(); k++) {
            if (h[k->to] + 1 == h[u] && k->cap > k->flow) {
                PushEdge(u, *k);
                if (!ex[u]) break;
            }
        }
        if (!ex[u]) return;
        if (gap[h[u]].empty()) {
            for (int i = h[u] + 1; i <= min(maxH, n); i++) {
                for (auto v : gap[i]) {
                    ingap[v] = 0;
                }
                gap[i].clear();
            }
        }
        h[u] = inf;
        for (auto [to, cap, flow, anti] : e[u]) {
            if (cap > flow) {
                h[u] = min(h[u], h[to] + 1);
            }
        }
        if (h[u] >= n) return;
        maxH = max(maxH, h[u]);
        if (!ingap[u]) {
            gap[h[u]].push_back(u);
            ingap[u] = 1;
        }
    }
    void init(int t, bool f = 1) {
        ingap.assign(n + 1, 0);
        for (int i = 1; i <= maxH; i++) {
            gap[i].clear();
        }
        gobalcnt = 0, maxH = 0;
        queue<int> q;
        h.assign(n + 1, inf);
        h[t] = 0, q.push(t);
        while (q.size()) {
            int u = q.front();
            q.pop(), maxH = h[u];
            for (auto &[v, cap, flow, anti] : e[u]) {
                if (h[v] == inf && e[v][anti].cap > e[v][anti].flow) {
                    h[v] = h[u] + 1;
                    q.push(v);
                    if (f) {
                        gap[h[v]].push_back(v);
                        ingap[v] = 1;
                    }
                }
            }
        }
    }
    T work(int s, int t) {
        init(t, 0);
        if (h[s] == inf) return maxflow;
        h[s] = n;
        ex[s] = INF;
        ex[t] = -INF;
        for (auto k = e[s].begin(); k != e[s].end(); k++) {
            PushEdge(s, *k);
        }
        while (maxH > 0) {
            if (gap[maxH].empty()) {
                maxH--;
                continue;
            }
            int u = gap[maxH].back();
            gap[maxH].pop_back();
            ingap[u] = 0;
            PushPoint(u);
            if (gobalcnt >= 10 * n) {
                init(t);
            }
        }
        ex[s] -= INF;
        ex[t] += INF;
        return maxflow = ex[t];
    }
};
// void solve() {
//     int n, m, s, t;
//     cin >> n >> m >> s >> t;
//     PushRelabel<i64> flow(n);
//     for (int i = 0; i < m; i++) {
//         int u, v, c;
//         cin >> u >> v >> c;
//         flow.addedge(u, v, c);
//     }
//     flow.init(t);
//     cout << flow.work(s, t) << '\n';
// }
void solve() {
    int n, m;
    i64 c, d;
    cin >> n >> m >> c >> d;
    vector<string> a(n);
    for (int i = 0; i < n; i++) cin >> a[i];
    i64 ans = n * m * d;
    for (int i = 0; i <= max(n, m); i++) {
        PushRelabel<int> flow(n + m + 2);
        int s = 0, t = n + m + 1;
        for (int j = 1; j <= n; j++) {
            flow.add(s, j, i);
        }
        for (int j = 1; j <= m; j++) {
            flow.add(j + n, t, i);
        }
        int cnt = 0;
        for (int j = 0; j < n; j++) {
            for (int k = 0; k < m; k++) {
                if (a[j][k] == '.') {
                    flow.add(j + 1, k + n + 1, 1);
                    cnt++;
                }
            }
        }
        flow.init(t);
        int cur = flow.work(s, t);
        ans = min(ans, 1ll * (cnt - cur) * d + 1ll * i * c);
    }
    cout << ans << '\n';
}
int main() {
    ios::sync_with_stdio(0); cin.tie(0), cout.tie(0);
    int t = 1; 
    // cin >> t;
    while(t--) solve();
    return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 1ms
memory: 3604kb

input:

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

output:

4

result:

ok 1 number(s): "4"

Test #2:

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

input:

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

output:

2

result:

ok 1 number(s): "2"

Test #3:

score: 0
Accepted
time: 446ms
memory: 4564kb

input:

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

output:

109972100048

result:

ok 1 number(s): "109972100048"

Test #4:

score: 0
Accepted
time: 557ms
memory: 5124kb

input:

250 250 62722280 506434
*.**.***.*.*....*....*...**.*..**..****.*.*..*.*.*..*.....**..*.*.*.*****.*.**..*.**....***..*..*.*.*.**.*..*..*.**..*...**....**..*.*.***.*****.*****.***..**.***.****....*.*.**.**.*...****....*..*.**.**********.......********...***.**..*.....**.*..*
.*..********..*...*..****...

output:

8437726048

result:

ok 1 number(s): "8437726048"

Test #5:

score: -100
Time Limit Exceeded

input:

250 250 85956327 344333
..*.............*...*.....*...*..........*.........*...*.......*..***......*.*........*.*........*........*..*..*.............*.*........*....*..*................***...................*..*.............*..*.....*..**..............*..*......*.....*..**
.........*......*.*.........

output:


result: