QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#618195#5114. Cells ColoringmhwTL 1ms4540kbC++232.8kb2024-10-06 19:41:542024-10-06 19:41:56

Judging History

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

  • [2024-10-06 19:41:56]
  • 评测
  • 测评结果:TL
  • 用时:1ms
  • 内存:4540kb
  • [2024-10-06 19:41:54]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define endl '\n'
const int N = 1e5 + 5;

// 源点,汇点
int s, t;

int tot = 1, hea[N];
struct edge
{
    int next, to, dis;
} edge[N];                    // 链式前向星
void add(int u, int v, int w) // 起点,终点,权值
{
    edge[++tot] = {hea[u], v, w};
    hea[u] = tot;
}

// lv是每个点的层数,cur用于当前弧优化标记增广起点
int lv[600], cur[N];
int bfs() // bfs分层
{
    memset(lv, -1, sizeof lv);
    lv[s] = 0;
    memcpy(cur, hea, sizeof(hea)); // 当前弧优化初始化
    queue<int> q;
    q.push(s);
    while (!q.empty())
    {
        int p = q.front();
        q.pop();
        for (int i = hea[p]; i; i = edge[i].next)
        {
            int v = edge[i].to, w = edge[i].dis;
            if (w > 0 && lv[v] == -1)
                lv[v] = lv[p] + 1, q.push(v);
        }
    }
    return lv[t] != -1; // 如果汇点未访问过说明已经无法达到汇点,此时返回false
}
int dfs(int p = s, int flow = inf)
{
    if (p == t) return flow;
    int rmn = flow; // 剩余的流量
    for (int i = cur[p]; i && rmn; i = edge[i].next)
    {
        cur[p] = i;
        int v = edge[i].to, w = edge[i].dis;
        if (w > 0 && lv[v] == lv[p] + 1)
        {
            int c = dfs(v, min(w, rmn));
            rmn -= c;
            edge[i].dis -= c;
            edge[i ^ 1].dis += c;
        }
    }
    return flow - rmn;
}
int dinic()
{
    int ans = 0;
    while (bfs()) ans += dfs();
    return ans;
}

char a[260][260];
void solve()
{
    int n, m, c, d;
    cin >> n >> m >> c >> d;
    int num = 0, ans = inf;
    for (int i = 1; i <= n; i++) 
    {
        string s; cin >> s;
        for (int j = 1; j <= m; j++) 
        {
            a[i][j] = s[j - 1];
            if (a[i][j] == '.') num++;
        }
    }
    s = n + m + 1, t = n + m + 2;
    for (int k = 1; k <= num; k++)
    {
        tot = 1;
        memset(hea, 0, sizeof hea);
        for (int i = 1; i <= n; i++) 
        {
            for (int j = 1; j <= m; j++) 
            {
                if (a[i][j] == '.') 
                {
                    add(i, n + j, 1);
                    add(n + j, i, 0);
                }
            }
        }
        for (int i = 1; i <= n; i++) add(s, i, k), add(i, s, 0);
        for (int i = 1; i <= m; i++) add(i + n, t, k), add(t, i + n, 0);
        int t = dinic();
        // cout << t << ' ' << c * k + d * (num - t) << endl;
        if (t <= num) ans = min(ans, c * k + d * (num - t));
    }
    cout << ans << '\n';
}

signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    int T = 1;
    while (T--) solve();
    return 0;
}

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

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

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

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

output:

4

result:

ok 1 number(s): "4"

Test #2:

score: 0
Accepted
time: 1ms
memory: 4532kb

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: