QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#85772 | #5664. Printing Stickers | hos_lyric | WA | 2ms | 3752kb | C++14 | 9.2kb | 2023-03-08 14:45:12 | 2023-03-08 14:45:16 |
Judging History
answer
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using Int = long long;
template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
template <class Flow> struct MaxFlow {
// Watch out when using types other than int and long long.
static constexpr Flow FLOW_EPS = 1e-10L;
static constexpr Flow FLOW_INF = std::numeric_limits<Flow>::max();
int n, m;
vector<int> ptr, nxt, zu;
vector<Flow> capa;
explicit MaxFlow(int n_) : n(n_), m(0), ptr(n_, -1) {}
void ae(int u, int v, Flow w0, Flow w1 = 0) {
assert(0 <= u); assert(u < n);
assert(0 <= v); assert(v < n);
assert(0 <= w0);
assert(0 <= w1);
nxt.push_back(ptr[u]); zu.push_back(v); capa.push_back(w0); ptr[u] = m++;
nxt.push_back(ptr[v]); zu.push_back(u); capa.push_back(w1); ptr[v] = m++;
}
vector<int> see, lev, que;
Flow augment(int u, int t, Flow limFlow) {
if (u == t) return limFlow;
for (int &i = see[u]; ~i; i = nxt[i]) if (capa[i] > FLOW_EPS) {
const int v = zu[i];
if (lev[u] < lev[v]) {
const Flow f = augment(v, t, min(limFlow, capa[i]));
if (f > FLOW_EPS) { capa[i] -= f; capa[i ^ 1] += f; return f; }
}
}
return 0;
}
bool bfs(int s, int t) {
for (int u = 0; u < n; ++u) { see[u] = ptr[u]; lev[u] = -1; }
auto head = que.begin(), tail = que.begin();
for (lev[*tail++ = s] = 0; head != tail; ) {
const int u = *head++;
for (int i = ptr[u]; ~i; i = nxt[i]) if (capa[i] > FLOW_EPS) {
const int v = zu[i];
if (!~lev[v]) {
lev[*tail++ = v] = lev[u] + 1;
if (v == t) return true;
}
}
}
return false;
}
Flow run(int s, int t, Flow limFlow = FLOW_INF) {
see.resize(n); lev.resize(n); que.resize(n);
Flow flow = 0;
for (; flow + FLOW_EPS < limFlow && bfs(s, t); ) {
for (Flow f; (f = augment(s, t, limFlow - flow)) > FLOW_EPS; flow += f) {}
}
return flow;
}
};
////////////////////////////////////////////////////////////////////////////////
vector<int> uf;
int root(int u) {
return (uf[u] < 0) ? u : (uf[u] = root(uf[u]));
}
bool connect(int u, int v) {
u = root(u);
v = root(v);
if (u == v) return false;
if (uf[u] > uf[v]) swap(u, v);
uf[u] += uf[v];
uf[v] = u;
return true;
}
// undirected weighted graph
// separate ss[i] from others (ss[j] (i != j))
// can be achieved by partition uss
// ss should be distinct
template <class Flow> struct IsolatingCut {
int n;
vector<pair<pair<int, int>, Flow>> edges;
int ssLen;
vector<int> ss;
vector<vector<int>> uss;
vector<int> ids;
vector<Flow> costs;
IsolatingCut(int n_) : n(n_) {}
void ae(int u, int v, Flow w) {
assert(0 <= u); assert(u < n);
assert(0 <= v); assert(v < n);
edges.emplace_back(make_pair(u, v), w);
}
void rec(int l, int r, const vector<int> &us, const vector<pair<pair<int, int>, Flow>> &es) {
if (l + 1 == r) {
uss[l] = us;
} else {
const int mid = (l + r) / 2;
MaxFlow<Flow> mf(n + 2);
for (int i = l; i < mid; ++i) mf.ae(n, ss[i], mf.FLOW_INF);
for (const auto &e : es) mf.ae(e.first.first, e.first.second, e.second, e.second);
for (int i = mid; i < r; ++i) mf.ae(ss[i], n + 1, mf.FLOW_INF);
mf.run(n, n + 1);
vector<int> usL, usR;
for (const int u : us) ((~mf.lev[u]) ? usL : usR).push_back(u);
vector<pair<pair<int, int>, Flow>> esL, esR;
for (const auto &e : es) {
const bool sideU = ~mf.lev[e.first.first], sideV = ~mf.lev[e.first.second];
if (sideU && sideV) esL.push_back(e);
if (!sideU && !sideV) esR.push_back(e);
}
rec(l, mid, usL, esL);
rec(mid, r, usR, esR);
}
}
void run(const vector<int> &ss_) {
ss = ss_;
ssLen = ss.size();
vector<int> us(n);
for (int u = 0; u < n; ++u) us[u] = u;
uss.assign(ssLen, {});
rec(0, ssLen, us, edges);
ids.assign(n, -1);
for (int i = 0; i < ssLen; ++i) for (const int u : uss[i]) ids[u] = i;
costs.assign(ssLen, 0);
for (const auto &edge : edges) {
const int i = ids[edge.first.first], j = ids[edge.first.second];
if (i != j) {
costs[i] += edge.second;
costs[j] += edge.second;
}
}
}
};
constexpr int INF = 1001001001 / 2;
char buf[20010];
int M, N, H, V;
vector<string> A, B;
vector<vector<int>> D;
int main() {
for (int numCases; ~scanf("%d", &numCases); ) { for (int caseId = 1; caseId <= numCases; ++caseId) {
scanf("%d%d%d%d", &M, &N, &H, &V);
A.resize(M);
for (int x = 0; x < M; ++x) {
scanf("%s", buf);
A[x] = buf;
}
B.resize(M);
for (int x = 0; x < M; ++x) {
scanf("%s", buf);
B[x] = buf;
}
D.assign(M, vector<int>(N));
for (int x = 0; x < M; ++x) for (int y = 0; y < N; ++y) {
scanf("%d", &D[x][y]);
}
uf.assign(M * (2 * N) + 1, -1);
vector<vector<vector<int>>> usss(M + 1, vector<vector<int>>(N + 1));
for (int x = 0; x < M; ++x) for (int y = 0; y < N; ++y) {
const int u = x * (2 * N) + 2 * y + 0;
const int v = x * (2 * N) + 2 * y + 1;
const bool bu = (B[x][2 * y + 0] == '#');
const bool bv = (B[x][2 * y + 1] == '#');
if (A[x][y] == '/') {
if (bu) {
usss[x + 0][y + 0].push_back(u);
usss[x + 0][y + 1].push_back(u);
usss[x + 1][y + 0].push_back(u);
}
if (bv) {
usss[x + 0][y + 1].push_back(v);
usss[x + 1][y + 0].push_back(v);
usss[x + 1][y + 1].push_back(v);
}
} else {
if (bu) {
usss[x + 0][y + 0].push_back(u);
usss[x + 1][y + 0].push_back(u);
usss[x + 1][y + 1].push_back(u);
}
if (bv) {
usss[x + 0][y + 0].push_back(v);
usss[x + 0][y + 1].push_back(v);
usss[x + 1][y + 1].push_back(v);
}
}
}
for (int x = 0; x <= M; ++x) for (int y = 0; y <= N; ++y) if (!usss[x][y].empty()) {
const int u = usss[x][y][0];
for (const int v : usss[x][y]) {
connect(u, v);
}
}
vector<int> rs;
for (int x = 0; x < M; ++x) for (int z = 0; z < 2 * N; ++z) if (B[x][z] == '#') {
const int u = x * (2 * N) + z;
if (uf[u] < 0) {
rs.push_back(u);
}
}
// cerr<<"rs = "<<rs<<endl;
// for(int x=0;x<M;++x){for(int z=0;z<2*N;++z)fprintf(stderr,"%3d ",root(x*(2*N)+z));cerr<<endl;}
IsolatingCut<int> ic(M * (2 * N) + 1);
auto ae = [&](int x0, int z0, int x1, int z1, int c) -> void {
const int u = root(x0 * (2 * N) + z0);
const int v = root(x1 * (2 * N) + z1);
const int cc = (B[x0][z0] != '#' && (x1 == M || B[x1][z1] != '#')) ? c : INF;
ic.ae(u, v, cc);
};
for (int x = 0; x < M; ++x) for (int y = 0; y < N; ++y) {
if (x + 1 < M) {
ae(
x , 2 * y + ((A[x ][y] == '/') ? 1 : 0),
x + 1, 2 * y + ((A[x + 1][y] == '/') ? 0 : 1),
H
);
}
if (y + 1 < N) {
ae(
x, 2 * y + 1,
x, 2 * (y + 1) + 0,
V
);
}
}
for (int y = 0; y < N; ++y) {
ae(
0, 2 * y + ((A[0][y] == '/') ? 0 : 1),
M, 0,
H
);
ae(
M - 1, 2 * y + ((A[M - 1][y] == '/') ? 1 : 0),
M, 0,
H
);
}
for (int x = 0; x < M; ++x) {
ae(
x, 2 * 0 + 0,
M, 0,
V
);
ae(
x, 2 * (N - 1) + 1,
M, 0,
V
);
}
for (int x = 0; x < M; ++x) for (int y = 0; y < N; ++y) {
ae(
x, 2 * y + 0,
x, 2 * y + 1,
D[x][y]
);
}
rs.push_back(M * (2 * N));
ic.run(rs);
auto ans = ic.costs;
ans.pop_back();
sort(ans.begin(), ans.end());
const int ansLen = ans.size();
printf("%d\n", ansLen);
for (int h = 0; h < ansLen; ++h) {
if (h) printf(" ");
printf("%d", ans[h]);
}
puts("");
}
#ifndef LOCAL
break;
#endif
}
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 2ms
memory: 3620kb
input:
1 4 9 10 10 \////\\/\ \\/\//\// //\\/\\/\ \///\//\/ .....#...##....... .##.#.....##...##. ...#.##....####... ..#.........#..##. 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
output:
2 86 106
result:
ok 2 lines
Test #2:
score: 0
Accepted
time: 2ms
memory: 3668kb
input:
1 8 12 20 19 \//\//\/\\\/ //\/\\\///// ///\/\\\\//\ \//\\\/\/\/\ \\\\\///\/// ///\\\\\\\\\ //\/////\\\\ /////\////// ........................ ..##################.... ..##..............##.... ..##..######....##...... ..##..##......####..##.. ..##........##......##.. ..############....####.. ...........
output:
3 196 214 723
result:
ok 2 lines
Test #3:
score: -100
Wrong Answer
time: 0ms
memory: 3752kb
input:
4 4 9 10 10 \////\\/\ \\/\//\// //\\/\\/\ \///\//\/ .....#...##....... .##.#.....##...##. ...#.##....####... ..#.........#..##. 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 12 20 19 \//\//\/\\\/ //\/\\\///// ///\/\\\\//\ \//\\\/\/\/\ \\\\\///\/// ///\\\\\\\\\ //\/////\\\...
output:
2 86 106 3 196 214 723 3 130 159 550 1 42
result:
wrong answer 6th lines differ - expected: '104 159 537', found: '130 159 550'