Salvens

2-sat

Jul 8th, 2024
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.51 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. //#define int long long
  6.  
  7. #define IOS ios::sync_with_stdio(false); cin.tie(nullptr);
  8.  
  9. //#include <ext/pb_ds/assoc_container.hpp>
  10. //using namespace __gnu_pbds;
  11. //typedef tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
  12. //std::mt19937 rnd(std::chrono::steady_clock::now().time_since_epoch().count());
  13.  
  14. const int INF = 1e9 + 7;
  15. const double EPS = 1e-6;
  16. const int MOD = 1e9 + 7;
  17. const int MAXN = 1e5 + 100;
  18.  
  19. int dx[] = {-1, 0, 1, 0};
  20. int dy[] = {0, 1, 0, -1};
  21.  
  22. struct TwoSatSolver {
  23. int n_vars;
  24. int n_vertices;
  25. vector<vector<int>> adj, adj_t;
  26. vector<bool> used;
  27. vector<int> order, comp;
  28. vector<bool> assignment;
  29.  
  30. 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) {
  31. order.reserve(n_vertices);
  32. }
  33. void dfs1(int v) {
  34. used[v] = true;
  35. for (int u : adj[v]) {
  36. if (!used[u])
  37. dfs1(u);
  38. }
  39. order.push_back(v);
  40. }
  41.  
  42. void dfs2(int v, int cl) {
  43. comp[v] = cl;
  44. for (int u : adj_t[v]) {
  45. if (comp[u] == -1)
  46. dfs2(u, cl);
  47. }
  48. }
  49.  
  50. bool solve_2SAT() {
  51. order.clear();
  52. used.assign(n_vertices, false);
  53. for (int i = 0; i < n_vertices; ++i) {
  54. if (!used[i])
  55. dfs1(i);
  56. }
  57.  
  58. comp.assign(n_vertices, -1);
  59. for (int i = 0, j = 0; i < n_vertices; ++i) {
  60. int v = order[n_vertices - i - 1];
  61. if (comp[v] == -1)
  62. dfs2(v, j++);
  63. }
  64.  
  65. assignment.assign(n_vars, false);
  66. for (int i = 0; i < n_vertices; i += 2) {
  67. if (comp[i] == comp[i + 1])
  68. return false;
  69. assignment[i / 2] = comp[i] > comp[i + 1];
  70. }
  71. return true;
  72. }
  73.  
  74. void add_disjunction(int a, bool na, int b, bool nb) {
  75. a = 2 * a ^ na;
  76. b = 2 * b ^ nb;
  77. int neg_a = a ^ 1;
  78. int neg_b = b ^ 1;
  79. adj[neg_a].push_back(b);
  80. adj[neg_b].push_back(a);
  81. adj_t[b].push_back(neg_a);
  82. adj_t[a].push_back(neg_b);
  83. }
  84. };
  85.  
  86. inline void solve() {
  87. int n, m;
  88. cin >> n >> m;
  89. vector<vector<int>> a(n, vector<int>(m));
  90. for (int i = 0; i < n; ++i) {
  91. for (int j = 0; j < m; ++j) {
  92. cin >> a[i][j];
  93. }
  94. }
  95.  
  96. TwoSatSolver solver(n * m);
  97. set<pair<int, int>> pairs;
  98. for (int i = 0; i < n; ++i) {
  99. for (int j = 0; j < m; ++j) {
  100. for (int k = 0; k < 4; ++k) {
  101. int x = i + dx[k], y = j + dy[k];
  102. if (x >= 0 && x < n && y >= 0 && y < m) {
  103. if (a[i][j] == a[x][y]) {
  104. int u = i * m + j, v = x * m + y;
  105. if (u > v) swap(u, v);
  106. pairs.insert({u, v});
  107. }
  108. if (a[i][j] + 1 == a[x][y]) {
  109. int u = i * m + j, v = x * m + y;
  110. if (u > v) swap(u, v);
  111. pairs.insert({u, v});
  112. }
  113. if (a[x][y] + 1 == a[i][j]) {
  114. int u = i * m + j, v = x * m + y;
  115. if (u > v) swap(u, v);
  116. pairs.insert({u, v});
  117. }
  118. }
  119. }
  120. }
  121. }
  122.  
  123. for (auto [u, v] : pairs) {
  124. int val_u = a[u / m][u % m], val_v = a[v / m][v % m];
  125. if (val_u == val_v) {
  126. solver.add_disjunction(u, true, v, true);
  127. } else if (val_u + 1 == val_v) {
  128. solver.add_disjunction(u, false, v, true);
  129. } else {
  130. solver.add_disjunction(u, true, v, false);
  131. }
  132. }
  133.  
  134. if (!solver.solve_2SAT()) {
  135. cout << "-1\n";
  136. return;
  137. }
  138.  
  139. int top = 0;
  140. for (int i = 0; i < n; ++i) {
  141. for (int j = 0; j < m; ++j) {
  142. cout << a[i][j] + solver.assignment[top++] << ' ';
  143. }
  144. cout << '\n';
  145. }
  146. cout << '\n';
  147. }
  148.  
  149. int32_t main() {
  150. IOS;
  151. // freopen("processing.in", "r", stdin);
  152. // freopen("processing.out", "w", stdout);
  153. clock_t tStart = clock();
  154.  
  155. int tt = 1;
  156. cin >> tt;
  157. while (tt --> 0) {
  158. solve();
  159. }
  160. // cerr << "Runtime is:" << (long double) (clock() - tStart) / CLOCKS_PER_SEC << '\n';
  161. return 0;
  162. }
Advertisement
Add Comment
Please, Sign In to add comment