QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#346153#3201. Cairo CorridorKhNURE_KIVI#AC ✓19ms27196kbC++209.1kb2024-03-07 21:22:322024-03-07 21:22:33

Judging History

This is the latest submission verdict.

  • [2024-03-07 21:22:33]
  • Judged
  • Verdict: AC
  • Time: 19ms
  • Memory: 27196kb
  • [2024-03-07 21:22:32]
  • Submitted

answer

//#pragma GCC optimize("Ofast", "unroll-loops")
//#pragma GCC target("sse", "sse2", "sse3", "ssse3", "sse4")

#include <bits/stdc++.h>

#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <set>
#include <stack>
#include <map>
#include <unordered_map>
#include <iomanip>
#include <cmath>
#include <queue>
#include <bitset>
#include <numeric>
#include <array>
#include <cstring>
#include <random>
#include <chrono>
#include <cassert>

#define all(a) a.begin(),a.end()
#define len(a) (int)(a.size())
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
#define fi first
#define se second



using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;

template<typename T>
bool umin(T &a, T b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}

template<typename T>
bool umax(T &a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

#ifdef KIVI
#define DEBUG for (bool _FLAG = true; _FLAG; _FLAG = false)
#define LOG(...) print(#__VA_ARGS__" ::", __VA_ARGS__) << endl

template<class ...Ts>
auto &print(Ts ...ts) { return ((cerr << ts << " "), ...); }

#else
#define DEBUG while (false)
#define LOG(...)
#endif

mt19937 rng(4242);

const int max_n = 250 * 500 + 42, inf = 1000111222;

struct dsu {
    int p_or_sz[max_n];

    void init(int n) {
        for (int i = 0; i < n; ++i) {
            p_or_sz[i] = -1;
        }
    }

    int find_set(int v) {
        if (p_or_sz[v] < 0) {
            return v;
        }
        return p_or_sz[v] = find_set(p_or_sz[v]);
    }

    bool union_set(int v1, int v2) {
        v1 = find_set(v1);
        v2 = find_set(v2);
        if (v1 == v2) {
            return false;
        }
        if (-p_or_sz[v1] > -p_or_sz[v2]) {
            swap(v1, v2);
        }
        p_or_sz[v2] += p_or_sz[v1];
        p_or_sz[v1] = v2;
        return true;
    }
};

vector<int> g[max_n];

bool used[max_n];

vector<int> visited;

array<int, 4> tot_state, state[max_n]; //up, down, left, right

void dfs(int v) {
    for(int i = 0; i < 4; i++) tot_state[i] += state[v][i];
    visited.pb(v);
    used[v] = true;
    for(auto& to : g[v])
        if(!used[to])
            dfs(to);
}

namespace barik
{
    int tin[max_n];
    int fup[max_n];
    int tout[max_n];
    int curt;
    vector<int> cur;
    vector<int> g2[2*max_n];
    int bicomps;

    array<int, 4> total_down[2*max_n];


    void dfs_barik(int v,int p)
    {
        cur.pb(v);
        tin[v]=fup[v]=++curt;
        for (auto to:g[v]){
            if (to==p){
                continue;
            }
            if (!tin[to]){
                dfs_barik(to,v);
                if (tin[v]<=fup[to]){
                    g2[v].pb(max_n+bicomps);
                    while (g2[max_n+bicomps].empty() || g2[max_n+bicomps].back()!=to){
                        g2[max_n+bicomps].pb(cur.back());
                        cur.pop_back();
                    }
                    bicomps++;
                }
                fup[v]=min(fup[v],fup[to]);
            }
            else{
                fup[v]=min(fup[v],tin[to]);
            }
        }
    }
    void dfs_barik_tree_g2(int v,int p,bool& is_ok)
    {
        if (v<max_n){
            total_down[v]=state[v];
        }
        else{
            total_down[v]={0,0,0,0};
        }
        for (auto to:g2[v]){
            if (to==p){
                continue;
            }
            dfs_barik_tree_g2(to,v,is_ok);
            bool flag=1;
            for (int j=0;j<4;j++){
                flag&=(total_down[to][j]!=0);
            }
            if (flag){
                is_ok=0;
            }
            for (int j=0;j<4;j++){
                total_down[v][j]+=total_down[to][j];
            }
        }

        if (p!=-1){
            bool flag=1;
            for (int j=0;j<4;j++){
                flag&=(tot_state[j]!=total_down[v][j]);
            }
            if (flag){
                is_ok=0;
            }
        }
    }

    void solve(const vector<int>& visited,bool& is_ok)
    {
        DEBUG{
            for (auto i:visited){
                cerr<<i<<"    ";
                cerr<<"with values (";
                for (int j=0;j<4;j++){
                    cerr<<" "<<state[i][j]<<" ";
                }
                cerr<<" ) ";
                cerr<<"  ->   ";
                for (auto j:g[i]){
                    cerr<<j<<" ";
                }
                cerr<<"\n";
            }
        };
        {
            dfs_barik(visited[0],-1);
            dfs_barik_tree_g2(visited[0],-1,is_ok);
        }

        for (auto i:visited){
            tin[i]=0;
            fup[i]=0;
            tout[i]=0;
        }
        curt=0;
        cur.clear();
        for (auto i:visited){
            g2[i].clear();
        }
        for (int i=max_n;i<=max_n+bicomps+1;i++){
            g2[i].clear();
        }
        bicomps=0;
    }
}

void solve() {
    for(int i = 0; i < max_n; i++) g[i].clear();
    int n, m;
    cin >> n >> m;
    vector<string> s(n);
    for(int i = 0; i < n; i++) cin >> s[i];
    int cind = 0;
    int in_row = m * 2;
    vector<pair<int, int> > edges;
    auto is_white = [&](int x) {
        return s[x / in_row][x % in_row] == '0';
    };
    auto add_edge = [&](int a, int b) {
        if(is_white(a) && is_white(b)) {
            edges.pb({a, b});
            g[a].pb(b);
            g[b].pb(a);
        }
    };
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            if((i + j) % 2 == 0) { // --
                add_edge(cind, cind + 1);
                if(j - 1 >= 0) {
                    add_edge(cind - 1, cind);
                    add_edge(cind - 2, cind);
                }
                if(i - 1 >= 0) {
                    add_edge(cind, cind - in_row + 1);
                    add_edge(cind + 1, cind - in_row + 1);
                }
            } else { // |
                add_edge(cind, cind + 1);
                if(j - 1 >= 0) {
                    add_edge(cind - 1, cind);
                    add_edge(cind - 1, cind + 1);
                }
                if(i - 1 >= 0) {
                    add_edge(cind, cind - in_row);
                    add_edge(cind, cind - in_row + 1);
                }
            }
            cind += 2;
        }
    }
    //todo test edges
    cind = 0;
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            array<int, 4> cind0 = {0, 0, 0, 0}, cind1 = {0, 0, 0, 0};
            if((i + j) % 2 == 0) { // --
                if(i == 0) {
                    cind0[0] = 1;
                    cind1[0] = 1;
                }
                if(j == 0) {
                    cind0[2] = 1;
                }
                if(i == n - 1) {
                    cind0[1] = 1;
                    cind1[1] = 1;
                }
                if(j == m - 1) {
                    cind1[3] = 1;
                }
            } else { // |
                if(i == 0) {
                    cind0[0] = 1;
                }
                if(j == 0) {
                    cind0[2] = 1;
                    cind1[2] = 1;
                }
                if(i == n - 1) {
                    cind1[1] = 1;
                }
                if(j == m - 1) {
                    cind0[3] = 1;
                    cind1[3] = 1;
                }
            }
            state[cind + 0] = cind0;
            state[cind + 1] = cind1;
            cind += 2;
        }
    }
    //todo test states
    for(int i = 0; i < max_n; i++) used[i] = false;
    for(int i = 0; i < n * in_row; i++)
        if(!used[i] && is_white(i)) {
            visited.clear();
            tot_state = {0, 0, 0, 0};
            dfs(i);
            if(tot_state[0] && tot_state[1] && tot_state[2] && tot_state[3]) {
                bool is_ok = true;
                int amv = len(visited);
                vector<bool> is_good(max_n);
                for(auto& x : visited) is_good[x] = true;
                vector<pair<int, int> > nedges;
                for(auto& x : edges)
                    if(is_good[x.fi] && is_good[x.se])
                        nedges.pb(x);
                edges.swap(nedges);
                for(int j = 0; j < max_n; j++) g[j].clear();
                for(auto& x : edges) {
                    g[x.fi].pb(x.se);
                    g[x.se].pb(x.fi);
                }
                barik::solve(visited,is_ok);
                //todo
                if(is_ok) cout << amv << '\n';
                else cout << "NO MINIMAL CORRIDOR\n";
                return;
            }
        }
    cout << "NO MINIMAL CORRIDOR\n";
}

int main() {
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    ios_base::sync_with_stdio(0);
    cin.tie(0);

    int t = 1;

    cin >> t;

    while (t--) solve();

}

/*
KIVI
*/

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 2ms
memory: 8112kb

input:

2
6 6
010101001001
001000101100
110101001101
010010000100
001110110010
001001101010
6 6
010010110010
001100100111
000110100101
011001100101
100100011100
011010001101

output:

17
NO MINIMAL CORRIDOR

result:

ok 2 lines

Test #2:

score: 0
Accepted
time: 1ms
memory: 7772kb

input:

1
3 4
11110111
01000000
11110111

output:

9

result:

ok single line: '9'

Test #3:

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

input:

7
1 1
00
1 1
10
1 1
01
2 1
00
00
2 1
10
00
3 1
10
00
01
3 1
10
00
00

output:

2
NO MINIMAL CORRIDOR
NO MINIMAL CORRIDOR
NO MINIMAL CORRIDOR
3
4
NO MINIMAL CORRIDOR

result:

ok 7 lines

Test #4:

score: 0
Accepted
time: 3ms
memory: 7792kb

input:

9
3 3
000100
100100
001110
3 3
000101
100100
000010
2 3
101111
010001
3 3
000101
100100
001100
3 3
011100
001001
001000
1 56
0001001000010010000100100001001000010010000100100001001000010010000100100001001000010010000100100001001000010010
1 56
000100100001001000010010000100100001001000010010000100100...

output:

NO MINIMAL CORRIDOR
7
5
NO MINIMAL CORRIDOR
NO MINIMAL CORRIDOR
84
NO MINIMAL CORRIDOR
79
NO MINIMAL CORRIDOR

result:

ok 9 lines

Test #5:

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

input:

4
6 6
010101001001
011000101100
110101001101
110010000100
001110000010
001001101010
6 6
101010010010
001010001010
011011101011
001001001011
101010011001
110101001101
6 6
010010110010
001110100111
000110101101
011001100101
100100011100
011010001101
6 6
000010101000
000011010100
110110011101
010000111...

output:

NO MINIMAL CORRIDOR
NO MINIMAL CORRIDOR
NO MINIMAL CORRIDOR
NO MINIMAL CORRIDOR

result:

ok 4 lines

Test #6:

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

input:

8
10 9
101111001001111101
110001101110101101
101101001010010111
011111011100010101
100101001011101101
010110011111011001
101000100001001000
011110110010101110
100100110110100001
000101100111011111
11 11
0110100101010010111101
1011000110100101110100
0011000100111100011010
1111110101100101000100
00011...

output:

29
NO MINIMAL CORRIDOR
NO MINIMAL CORRIDOR
NO MINIMAL CORRIDOR
43
NO MINIMAL CORRIDOR
55
NO MINIMAL CORRIDOR

result:

ok 8 lines

Test #7:

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

input:

4
2 2
0010
0011
3 3
111000
010111
100111
11 10
11111111011111111111
11111111001111111111
11111111101111111111
11111111001111111111
11111111011111100001
11111111000010011111
11111001011111111111
11100111111111111111
10001111111111111111
01101111111111111111
10011111111111111111
6 6
010101001001
00100...

output:

NO MINIMAL CORRIDOR
7
29
NO MINIMAL CORRIDOR

result:

ok 4 lines

Test #8:

score: 0
Accepted
time: 10ms
memory: 16404kb

input:

2
125 125
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000...

output:

NO MINIMAL CORRIDOR
NO MINIMAL CORRIDOR

result:

ok 2 lines

Test #9:

score: 0
Accepted
time: 4ms
memory: 22772kb

input:

1
249 249
01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000...

output:

745

result:

ok single line: '745'

Test #10:

score: 0
Accepted
time: 15ms
memory: 23104kb

input:

1
249 250
01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000...

output:

746

result:

ok single line: '746'

Test #11:

score: 0
Accepted
time: 3ms
memory: 23332kb

input:

1
250 249
01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000...

output:

746

result:

ok single line: '746'

Test #12:

score: 0
Accepted
time: 12ms
memory: 22832kb

input:

1
250 250
01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000...

output:

748

result:

ok single line: '748'

Test #13:

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

input:

2
100 100
00100000101011101100100000001100011100100011000100010100010000000000101110100100001010111000101011011000101111111101011100110100001100001100100101100010001011110011110011110100001100001110011011001010
11110111011101110111111101110111011111110111011111111111111101110111011111110111111101110...

output:

7378
NO MINIMAL CORRIDOR

result:

ok 2 lines

Test #14:

score: 0
Accepted
time: 9ms
memory: 21092kb

input:

1
200 200
00100100000110001100010110101101000011100011001111010011000101111010111000011000010011011100110010010101100110010100000101001101001110100010011000100000101101001101111111010010110101010010001101010111010011110101100001000100000010010010000001110110101010110000100100111110101100000001010011...

output:

29753

result:

ok single line: '29753'

Test #15:

score: 0
Accepted
time: 5ms
memory: 10084kb

input:

1
200 200
11010011001011011100011000100111100001110000000110001100111010101011111110011001011011000101100010110110100100101110001101010111111000010010001100110100000110001110011001100110111101000111010101100111001000001110000110101101011000101110011111111000000011000111001100010101100001110111101001...

output:

NO MINIMAL CORRIDOR

result:

ok single line: 'NO MINIMAL CORRIDOR'

Test #16:

score: 0
Accepted
time: 19ms
memory: 27196kb

input:

1
240 240
10010001010111000111011011000100010110100111011011001111011011000110001001010110111101111000110110000101110011100101111100110110010100110111001011101001111100101101110101011101000111010010101010011110010101011010011000111011000011100010111011111000110001011001111000111010011000010110010000...

output:

42903

result:

ok single line: '42903'

Test #17:

score: 0
Accepted
time: 8ms
memory: 12472kb

input:

1
240 240
10100111110110011001001111000000011011101011001011001010101110101010111010000110001011111000001100010110111001001000000010101001111101111100101110100010011001110011011111001101010011000110101001011010001101111100110111101001101110000001011000001000111000101001101100110110101001001010010100...

output:

NO MINIMAL CORRIDOR

result:

ok single line: 'NO MINIMAL CORRIDOR'

Test #18:

score: 0
Accepted
time: 3ms
memory: 6844kb

input:

6
40 40
01000000000000000000000000000000000000000000000000000000000000000000000000000000
00100000000000000000000000000000000000000000000000000000000000000000000000000000
01000000000000000000000000000000000000000000000000000000000000000000000000000000
0010000000000000000000000000000000000000000000000...

output:

118
118
NO MINIMAL CORRIDOR
NO MINIMAL CORRIDOR
NO MINIMAL CORRIDOR
NO MINIMAL CORRIDOR

result:

ok 6 lines

Test #19:

score: 0
Accepted
time: 3ms
memory: 8272kb

input:

9
27 27
000000000000000000000000000000000000000000000000000010
000000000000000000000000000000000000000000000000000100
000000000000000000000000000000000000000000000000000010
000000000000000000000000000000000000000000000000000100
000000000000000000000000000000000000000000000000000010
00000000000000000...

output:

79
79
79
NO MINIMAL CORRIDOR
NO MINIMAL CORRIDOR
NO MINIMAL CORRIDOR
NO MINIMAL CORRIDOR
NO MINIMAL CORRIDOR
NO MINIMAL CORRIDOR

result:

ok 9 lines