QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#618195 | #5114. Cells Coloring | mhw | TL | 1ms | 4540kb | C++23 | 2.8kb | 2024-10-06 19:41:54 | 2024-10-06 19:41:56 |
Judging History
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 ..**.*****..**..**.*****..***..***.**......*.***.*...***.*....*.**.*.**.*.*.****...*.******.***.************....**.*..*..***.*******.*.***.*..**..****.**.*.*..***.****..**.....***.....*.****...*...*.***..****..**.*.*******..*.*******.*.*.*.****.*.*** ....**.*******.*.******...