Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- //#define int long long
- #define IOS ios::sync_with_stdio(false); cin.tie(nullptr);
- //#include <ext/pb_ds/assoc_container.hpp>
- //using namespace __gnu_pbds;
- //typedef tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
- //std::mt19937 rnd(std::chrono::steady_clock::now().time_since_epoch().count());
- const int INF = 1e9 + 7;
- const double EPS = 1e-6;
- const int MOD = 1e9 + 7;
- const int MAXN = 1e5 + 100;
- int dx[] = {-1, 0, 1, 0};
- int dy[] = {0, 1, 0, -1};
- struct TwoSatSolver {
- int n_vars;
- int n_vertices;
- vector<vector<int>> adj, adj_t;
- vector<bool> used;
- vector<int> order, comp;
- vector<bool> assignment;
- TwoSatSolver(int _n_vars) : n_vars(_n_vars), n_vertices(2 * n_vars), adj(n_vertices), adj_t(n_vertices), used(n_vertices), order(), comp(n_vertices, -1), assignment(n_vars) {
- order.reserve(n_vertices);
- }
- void dfs1(int v) {
- used[v] = true;
- for (int u : adj[v]) {
- if (!used[u])
- dfs1(u);
- }
- order.push_back(v);
- }
- void dfs2(int v, int cl) {
- comp[v] = cl;
- for (int u : adj_t[v]) {
- if (comp[u] == -1)
- dfs2(u, cl);
- }
- }
- bool solve_2SAT() {
- order.clear();
- used.assign(n_vertices, false);
- for (int i = 0; i < n_vertices; ++i) {
- if (!used[i])
- dfs1(i);
- }
- comp.assign(n_vertices, -1);
- for (int i = 0, j = 0; i < n_vertices; ++i) {
- int v = order[n_vertices - i - 1];
- if (comp[v] == -1)
- dfs2(v, j++);
- }
- assignment.assign(n_vars, false);
- for (int i = 0; i < n_vertices; i += 2) {
- if (comp[i] == comp[i + 1])
- return false;
- assignment[i / 2] = comp[i] > comp[i + 1];
- }
- return true;
- }
- void add_disjunction(int a, bool na, int b, bool nb) {
- a = 2 * a ^ na;
- b = 2 * b ^ nb;
- int neg_a = a ^ 1;
- int neg_b = b ^ 1;
- adj[neg_a].push_back(b);
- adj[neg_b].push_back(a);
- adj_t[b].push_back(neg_a);
- adj_t[a].push_back(neg_b);
- }
- };
- inline void solve() {
- int n, m;
- cin >> n >> m;
- vector<vector<int>> a(n, vector<int>(m));
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < m; ++j) {
- cin >> a[i][j];
- }
- }
- TwoSatSolver solver(n * m);
- set<pair<int, int>> pairs;
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < m; ++j) {
- for (int k = 0; k < 4; ++k) {
- int x = i + dx[k], y = j + dy[k];
- if (x >= 0 && x < n && y >= 0 && y < m) {
- if (a[i][j] == a[x][y]) {
- int u = i * m + j, v = x * m + y;
- if (u > v) swap(u, v);
- pairs.insert({u, v});
- }
- if (a[i][j] + 1 == a[x][y]) {
- int u = i * m + j, v = x * m + y;
- if (u > v) swap(u, v);
- pairs.insert({u, v});
- }
- if (a[x][y] + 1 == a[i][j]) {
- int u = i * m + j, v = x * m + y;
- if (u > v) swap(u, v);
- pairs.insert({u, v});
- }
- }
- }
- }
- }
- for (auto [u, v] : pairs) {
- int val_u = a[u / m][u % m], val_v = a[v / m][v % m];
- if (val_u == val_v) {
- solver.add_disjunction(u, true, v, true);
- } else if (val_u + 1 == val_v) {
- solver.add_disjunction(u, false, v, true);
- } else {
- solver.add_disjunction(u, true, v, false);
- }
- }
- if (!solver.solve_2SAT()) {
- cout << "-1\n";
- return;
- }
- int top = 0;
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < m; ++j) {
- cout << a[i][j] + solver.assignment[top++] << ' ';
- }
- cout << '\n';
- }
- cout << '\n';
- }
- int32_t main() {
- IOS;
- // freopen("processing.in", "r", stdin);
- // freopen("processing.out", "w", stdout);
- clock_t tStart = clock();
- int tt = 1;
- cin >> tt;
- while (tt --> 0) {
- solve();
- }
- // cerr << "Runtime is:" << (long double) (clock() - tStart) / CLOCKS_PER_SEC << '\n';
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment