QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#770816#5668. Cell Nuclei DetectionvwxyzTL 0ms3612kbC++204.2kb2024-11-22 00:29:002024-11-22 00:29:01

Judging History

你现在查看的是最新测评结果

  • [2024-11-22 00:29:01]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:3612kb
  • [2024-11-22 00:29:00]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;
using ll=long long;

template <class T>
using V = vector<T>;
template <class T>
using VV = V<V<T>>;

template <class C>
struct MaxFlow {
  C flow;
  V<char> dual;  // false: S-side true: T-side
};
template <class C, class E>
struct MFExec {
  static constexpr C INF = numeric_limits<C>::max();
  C eps;
  VV<E>& g;
  int s, t;
  V<int> level, iter;
  C dfs(int v, C f) {
    if (v == t) return f;
    C res = 0;
    for (int& i = iter[v]; i < int(g[v].size()); i++) {
      E& e = g[v][i];
      if (e.cap <= eps || level[v] >= level[e.to]) continue;
      C d = dfs(e.to, min(f, e.cap));
      e.cap -= d;
      g[e.to][e.rev].cap += d;
      res += d;
      f -= d;
      if (f == 0) break;
    }
    return res;
  }
  MaxFlow<C> info;
  MFExec(VV<E>& _g, int _s, int _t, C _eps)
      : eps(_eps), g(_g), s(_s), t(_t) {
    int N = int(g.size());
    C& flow = (info.flow = 0);
    while (true) {
      queue<int> que;
      level = V<int>(N, -1);
      level[s] = 0;
      que.push(s);
      while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (E e : g[v]) {
          if (e.cap <= eps || level[e.to] >= 0) continue;
          level[e.to] = level[v] + 1;
          que.push(e.to);
        }
      }
      if (level[t] == -1) break;
      while (true) {
        iter = V<int>(N, 0);
        C f = dfs(s, INF);
        if (!f) break;
        flow += f;
      }
    }
    for (int i = 0; i < N; i++)
      info.dual.push_back(level[i] == -1);
  }
};
template <class C, class E>
MaxFlow<C> get_mf(VV<E>& g, int s, int t, C eps) {
  return MFExec<C, E>(g, s, t, eps).info;
}

struct TupleHash {
    template <class T>
    static inline void hash_combine(std::size_t& seed, const T& val) {
        seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
    }

    std::size_t operator()(const std::tuple<int, int, int, int>& t) const {
        std::size_t seed = 0;
        hash_combine(seed, std::get<0>(t));
        hash_combine(seed, std::get<1>(t));
        hash_combine(seed, std::get<2>(t));
        hash_combine(seed, std::get<3>(t));
        return seed;
    }
};

int main(){
    int T;
    cin>>T;
    while(T){
        T--;
        int M,N;
        cin>>M>>N;
        vector<tuple<int,int,int,int>> XY;
        for(int m=0;m<M;m++){
            int x1,y1,x2,y2;
            cin>>x1>>y1>>x2>>y2;
            XY.emplace_back(x1,y1,x2,y2);
        }
        unordered_map<tuple<int,int,int,int>,int,TupleHash> idx;
        for(int n=0;n<N;n++){
            int x1,y1,x2,y2;
            cin>>x1>>y1>>x2>>y2;
            idx[{x1,y1,x2,y2}]=n;
        }
        struct E {
            int to, rev, cap;
        };
        VV<E> g(N+M+2);
        auto add_edge = [&](int from, int to, int cap) {
            g[from].push_back(E{to, int(g[to].size()), cap});
            g[to].push_back(E{from, int(g[from].size())-1, 0});
        };
        int s=0;
        int t=M+N+1;
        for(int m=0;m<M;m++){
            add_edge(s,1+m,1);
        }
        for(int n=0;n<N;n++){
            add_edge(1+M+n,t,1);
        }
        for(int m=0;m<M;m++){
            auto [x1_,y1_,x2_,y2_]=XY[m];
            if(x1_+8<x2_){
                continue;
            }
            if(y1_+8<y2_){
                continue;
            }
            for(int x1=x1_-3;x1<x2_;x1++){
                for(int x2=max(x1+1,x1_+1);x2<x2_+4;x2++){
                    for(int y1=y1_-3;y1<y2_;y1++){
                        for(int y2=max(y1+1,y1_+1);y2<y2_+4;y2++){
                            int dx=max(0,min(x2,x2_)-max(x1,x1_));
                            int dy=max(0,min(y2,y2_)-max(y1,y1_));
                            if(2*dx*dy>=(x2_-x1_)*(y2_-y1_)){
                                if(idx.find({x1,y1,x2,y2})!=idx.end()){
                                    add_edge(1+m,1+M+idx[{x1,y1,x2,y2}],1);
                                }
                            }
                        }
                    }
                }
            }
        }
        int ans=get_mf(g,0,M+N+1,0).flow;
        cout<<ans<<"\n";
    }
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3612kb

input:

3
2 2
1 1 3 3
3 3 5 5
2 2 4 4
4 4 6 6
2 3
1 1 3 3
3 3 5 5
1 3 3 5
2 1 4 5
3 1 5 3
3 3
1 1 2 2
2 2 3 3
3 3 4 4
1 1 3 3
2 2 4 4
3 3 5 5

output:

0
1
3

result:

ok 3 lines

Test #2:

score: 0
Accepted
time: 0ms
memory: 3592kb

input:

3
2 2
1 1 3 3
3 3 5 5
2 2 4 4
4 4 6 6
2 3
1 1 3 3
3 3 5 5
1 3 3 5
2 1 4 5
3 1 5 3
3 3
1 1 2 2
2 2 3 3
3 3 4 4
1 1 3 3
2 2 4 4
3 3 5 5

output:

0
1
3

result:

ok 3 lines

Test #3:

score: -100
Time Limit Exceeded

input:

5
50000 50000
0 0 4 4
4 0 8 4
8 0 12 4
12 0 16 4
16 0 20 4
20 0 24 4
24 0 28 4
28 0 32 4
32 0 36 4
36 0 40 4
40 0 44 4
44 0 48 4
48 0 52 4
52 0 56 4
56 0 60 4
60 0 64 4
64 0 68 4
68 0 72 4
72 0 76 4
76 0 80 4
80 0 84 4
84 0 88 4
88 0 92 4
92 0 96 4
96 0 100 4
100 0 104 4
104 0 108 4
108 0 112 4
112 ...

output:

50000
50000
0
50000

result: