QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#85772#5664. Printing Stickershos_lyricWA 2ms3752kbC++149.2kb2023-03-08 14:45:122023-03-08 14:45:16

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-08 14:45:16]
  • 评测
  • 测评结果:WA
  • 用时:2ms
  • 内存:3752kb
  • [2023-03-08 14:45:12]
  • 提交

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'