Submission #1283025

#TimeUsernameProblemLanguageResultExecution timeMemory
1283025ishaanthenerdTracks in the Snow (BOI13_tracks)C++20
6.67 / 100
2115 ms473676 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll MOD = 1e9 + 7;
using pii = pair<int, int>;

bool in_bounds(int x, int y, int r, int c) {
    return x >= 0 && x < r && y >= 0 && y < c;
}

bool equal(pii p, pii q) {
    return p.first == q.first && p.second == q.second;
}

class DSU {
    public:
    map<pii, pii> parent;
    map<pii, int> treesize;

    void init(int h, int w) {
        for (int i = 0; i < h; i++) for (int j = 0; j < w; j++) parent[{i, j}] = {i, j};
        for (int i = 0; i < h; i++) for (int j = 0; j < w; j++) treesize[{i, j}] = 1;
    }

    pii find_set(pii p) {
        if (equal(p, parent[p])) return p;
        else {
            pii ans = find_set(parent[p]);
            parent[p] = ans;
            return ans;
        }
    }

    void union_set(pii p, pii q) {
        pii a = find_set(p), b = find_set(q);
        if (!equal(a, b)) {
            if (treesize[a] > treesize[b]) {
                parent[b] = a;
                treesize[a] += treesize[b];
            }
            else {
                parent[a] = b;
                treesize[b] += treesize[a];
            }
        }
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int h, w;
    cin >> h >> w;
    vector<vector<char>> grid(h, vector<char>(w, 0));
    for (int i = 0; i < h; i++) for (int j = 0; j < w; j++) cin >> grid.at(i).at(j);

    // connect adjacent DSU regions (edge connects two regions of separate color)
    DSU d;
    d.init(h, w);
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            for (int k = -2; k < 0; k++) {
                int dx = k % 2, dy = (k + 1) % 2;
                if (in_bounds(i + dx, j + dy, h, w) && grid.at(i).at(j) == grid.at(i + dx).at(j + dy)) {
                    d.union_set({i, j}, {i + dx, j + dy});
                }
            }
        }
    }

    // flood-fill on DSU graph to get answer!!
    map<pii, set<pii>> adj;
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            for (int k = -2; k < 0; k++) {
                int dx = k % 2, dy = (k + 1) % 2;
                if (in_bounds(i + dx, j + dy, h, w) && grid.at(i).at(j) != grid.at(i + dx).at(j + dy)) {
                    adj[d.find_set({i, j})].insert(d.find_set({i + dx, j + dy}));
                    adj[d.find_set({i + dx, j + dy})].insert(d.find_set({i, j}));
                }
            }
        }
    }

    map<pii, int> ans;
    for (auto x : adj) ans[x.first] = INT_MAX;
    ans[d.find_set({0, 0})] = 1;
    int final_ans = 1;
    queue<pii> q;
    q.push(d.find_set({0, 0}));
    while (!q.empty()) {
        pii p = q.front();
        q.pop();
        for (pii o : adj[p]) {
            if (ans[o] == INT_MAX) {
                ans[o] = 1 + ans[p];
                final_ans = max(final_ans, ans[o]);
                q.push(o);
            }
        }
    }
    cout << final_ans << endl;

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...