#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 < 2; 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 < 2; 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 time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |