QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#84102 | #5664. Printing Stickers | sugim48 | Compile Error | / | / | C++17 | 6.7kb | 2023-03-05 14:54:05 | 2023-03-05 14:54:08 |
Judging History
你现在查看的是最新测评结果
- [2023-08-10 23:21:45]
- System Update: QOJ starts to keep a history of the judgings of all the submissions.
- [2023-03-05 14:54:08]
- 评测
- 测评结果:Compile Error
- 用时:0ms
- 内存:0kb
- [2023-03-05 14:54:05]
- 提交
answer
#include <bits/stdc++.h>
#include <atcoder/maxflow>
using namespace std;
using namespace atcoder;
#define rep(i, N) for (int i = 0; (i) < (int)(N); (i)++)
#define all(x) begin(x), end(x)
#define pb push_back
using ll = long long;
using i_i = tuple<int, int>;
const int INF = INT_MAX / 10;
struct Edge { int u, v, w; };
struct union_find {
vector<int> v;
union_find(int n) : v(n, -1) {}
int find(int x) { return v[x] < 0 ? x : v[x] = find(v[x]); }
void unite(int x, int y) {
x = find(x); y = find(y);
if (x == y) return;
if (-v[x] < -v[y]) swap(x, y);
v[x] += v[y]; v[y] = x;
}
bool root(int x) { return v[x] < 0; }
bool same(int x, int y) { return find(x) == find(y); }
int size(int x) { return -v[find(x)]; }
};
vector<int> solve(int N, int M, int H, int V, vector<string> slash, vector<vector<bool>> black, vector<vector<int>> cost) {
auto f = [&](int i, int j, int z) -> int {
if (0 <= i && i < N && 0 <= j && j < M)
return (i * M + j) * 2 + z;
return -1;
};
auto is_black = [&](int u) -> bool {
return u != -1 && black[u / (M * 2)][u % (M * 2)];
};
vector<Edge> E;
auto add_edge = [&](int i1, int j1, int z1, int i2, int j2, int z2, int w) {
int u = f(i1, j1, z1);
int v = f(i2, j2, z2);
if (is_black(u) || is_black(v)) w = INF;
E.pb(Edge{u, v, w});
};
// vertical
rep(i, N) rep(j, M + 1) {
add_edge(i, j - 1, 1, i, j, 0, V);
}
// horizontal
rep(j, M) rep(i, N + 1) {
int z1 = (i - 1 >= 0 && slash[i - 1][j] == '\\') ? 0 : 1;
int z2 = (i < N && slash[i][j] == '/') ? 0 : 1;
add_edge(i - 1, j, z1, i, j, z2, H);
}
// diagonal
rep(i, N) rep(j, M) {
add_edge(i, j, 0, i, j, 1, cost[i][j]);
}
int L = E.size();
union_find uf(N * M * 2);
rep(i, N + 1) rep(j, M + 1) {
vector<int> vs;
// upper left
if (i - 1 >= 0 && j - 1 >= 0) {
vs.pb(f(i - 1, j - 1, 1));
if (slash[i - 1][j - 1] == '\\') {
vs.pb(f(i - 1, j - 1, 0));
}
}
// upper right
if (i - 1 >= 0 && j < M) {
vs.pb(f(i - 1, j, 0));
if (slash[i - 1][j] == '/') {
vs.pb(f(i - 1, j, 1));
}
}
// lower left
if (i < N && j - 1 >= 0) {
vs.pb(f(i, j - 1, 1));
if (slash[i][j - 1] == '/') {
vs.pb(f(i, j - 1, 0));
}
}
// lower right
if (i < N && j < M) {
vs.pb(f(i, j, 0));
if (slash[i][j] == '\\') {
vs.pb(f(i, j, 1));
}
}
vector<int> _vs;
for (int u: vs) if (is_black(u)) _vs.pb(u);
vs = _vs;
int K = vs.size();
for (int k = 0; k + 1 < K; k++)
uf.unite(vs[k], vs[k + 1]);
}
vector<vector<int>> components(N * M * 2);
rep(u, N * M * 2) if (is_black(u)) components[uf.find(u)].pb(u);
vector<vector<int>> _components;
for (auto vs: components) if (!vs.empty()) _components.pb(vs);
components = _components;
int C = components.size();
vector<bool> cut(L);
rep(l, L) if (E[l].u == -1 || E[l].v == -1) cut[l] = true;
rep(bit, 10) {
mf_graph<int> G(N * M * 2 + 2);
int s = N * M * 2;
int t = N * M * 2 + 1;
rep(l, L) if (!cut[l]) {
G.add_edge(E[l].u, E[l].v, E[l].w);
G.add_edge(E[l].v, E[l].u, E[l].w);
}
rep(c, C) {
auto vs = components[c];
for (int u: vs) {
if (c>>bit & 1) G.add_edge(s, u, INF);
else G.add_edge(u, t, INF);
}
}
G.flow(s, t);
vector<bool> reach = G.min_cut(s);
rep(l, L) if ((E[l].u != -1 && reach[E[l].u]) ^ (E[l].v != -1 && reach[E[l].v])) cut[l] = true;
}
{
mf_graph<int> G(N * M * 2 + C + 2);
int s = N * M * 2;
int t = N * M * 2 + 1;
rep(l, L) {
if (cut[l]) {
if (E[l].u != -1) G.add_edge(E[l].u, t, E[l].w);
if (E[l].v != -1) G.add_edge(E[l].v, t, E[l].w);
} else {
G.add_edge(E[l].u, E[l].v, E[l].w);
G.add_edge(E[l].v, E[l].u, E[l].w);
}
}
rep(c, C) {
auto vs = components[c];
for (int u: vs) G.add_edge(s, u, INF);
}
G.flow(s, t);
vector<bool> reach = G.min_cut(s);
rep(l, L) if ((E[l].u != -1 && reach[E[l].u]) ^ (E[l].v != -1 && reach[E[l].v])) cut[l] = true;
}
vector<int> ans(C);
{
vector<vector<int>> G(N * M * 2);
vector<int> unko(N * M * 2);
rep(l, L) {
Edge e = E[l];
if (cut[l]) {
if (e.u != -1) unko[e.u] += e.w;
if (e.v != -1) unko[e.v] += e.w;
} else {
G[e.u].pb(e.v);
G[e.v].pb(e.u);
}
}
vector<bool> vis(N * M * 2);
auto dfs = [&](auto self, int u, int c) {
if (vis[u]) return;
vis[u] = true;
ans[c] += unko[u];
unko[u] = 0;
for (int v: G[u]) self(self, v, c);
};
rep(c, C) {
auto vs = components[c];
for (int u: vs) dfs(dfs, u, c);
}
}
sort(all(ans));
return ans;
}
int main() {
cin.tie(nullptr);
ios_base::sync_with_stdio(false);
// rep(t, 50) {
// int N = 100;
// int M = 100;
// int H = 1000;
// int V = 1000;
// vector<string> slash(N, string(M, '/'));
// vector<vector<bool>> black(N, vector<bool>(M * 2));
// rep(i, 32) rep(j, 32) black[i * 3][j * 3 * 2] = true;
// vector<vector<int>> cost(N, vector<int>(M, rand() % 1000 + 1));
// solve(N, M, H, V, slash, black, cost);
// }
int T; cin >> T;
while (T--) {
int N, M, H, V;
cin >> N >> M >> H >> V;
vector<string> slash(N);
rep(i, N) cin >> slash[i];
vector<vector<bool>> black(N, vector<bool>(M * 2));
rep(i, N) {
string s; cin >> s;
rep(j, M * 2) black[i][j] = (s[j] == '#');
}
vector<vector<int>> cost(N, vector<int>(M));
rep(i, N) rep(j, M) cin >> cost[i][j];
auto ans = solve(N, M, H, V, slash, black, cost);
int K = ans.size();
cout << K << '\n';
rep(k, K) cout << ans[k] << (k + 1 < K ? ' ' : '\n');
}
}
Details
answer.code:2:10: fatal error: atcoder/maxflow: No such file or directory 2 | #include <atcoder/maxflow> | ^~~~~~~~~~~~~~~~~ compilation terminated.