QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#85767#5664. Printing Stickershos_lyricWA 15714ms5996kbC++148.1kb2023-03-08 14:27:402023-03-08 14:27:42

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:27:42]
  • 评测
  • 测评结果:WA
  • 用时:15714ms
  • 内存:5996kb
  • [2023-03-08 14:27:40]
  • 提交

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
// separate ss[i] from others (ss[j] (i != j))
// can be achieved by partition uss
template <class Flow> struct IsolatingCut {
  int n;
  vector<pair<pair<int, int>, Flow>> edges;

  int len;
  vector<int> ss;
  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 run(const vector<int> &ss_) {
    ss = ss_;
    len = ss.size();
    costs.assign(len, 0);
    for (int i = 0; i < len; ++i) {
      MaxFlow<Flow> mf(n + 1);
      for (const auto &edge : edges) {
        mf.ae(edge.first.first, edge.first.second, edge.second, edge.second);
      }
      for (int j = 0; j < len; ++j) if (i != j) {
        mf.ae(ss[j], n, mf.FLOW_INF);
      }
      costs[i] = mf.run(ss[i], n);
    }
  }
};


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);
    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 = x0 * (2 * N) + z0;
      const int v = 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: 0ms
memory: 3536kb

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: 1ms
memory: 3580kb

input:

1
8 12 20 19
\//\//\/\\\/
//\/\\\/////
///\/\\\\//\
\//\\\/\/\/\
\\\\\///\///
///\\\\\\\\\
//\/////\\\\
/////\//////
........................
..##################....
..##..............##....
..##..######....##......
..##..##......####..##..
..##........##......##..
..############....####..
...........

output:

3
196 214 723

result:

ok 2 lines

Test #3:

score: 0
Accepted
time: 2ms
memory: 3608kb

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
104 159 537
1
42

result:

ok 8 lines

Test #4:

score: -100
Wrong Answer
time: 15714ms
memory: 5996kb

input:

50
49 204 993 979
///\/\/\\\///\\//////\/\\\/\\\\//\\/\\\////\/\/\\\/\/\/\/\\/\/\/\///\/\\\//\///\/\\\\\/\//\\\\\\\\//\//\\\\\\//\///\///\\//\\/\/\\/\\/\\//\\\\\\/\\\//\/\////\\\\//\\////\\\/\///\/\//\\\//\///\\\/\\/\\\//\
\\//\\/\\///\//\\\\/\/\\\\\//\\/\/\////\\//\//\//\////\//\/\/\/\\\//\\////\//...

output:

26
4745 4847 5354 5486 5487 5688 5697 5702 5715 5731 5739 5744 5784 5839 6654 6689 7455 7733 8463 9218 9578 11334 12196 13358 14246 641453
583
4435 4444 4495 4497 4525 4528 4537 4551 4563 4573 4577 4585 4603 4610 4611 4643 4661 4663 4686 4699 4711 4715 4745 4778 4851 5310 5337 5362 5365 5389 5406 54...

result:

wrong answer 2nd lines differ - expected: '4745 4847 5354 5486 5487 5697 ... 11334 12254 13358 16125 645597', found: '4745 4847 5354 5486 5487 5688 ... 11334 12196 13358 14246 641453'