fork download
  1. /* cerberus97 - Hanit Banga */
  2.  
  3. #include <iostream>
  4. #include <iomanip>
  5. #include <cassert>
  6. #include <cmath>
  7. #include <cstdio>
  8. #include <cstring>
  9. #include <cstdlib>
  10. #include <map>
  11. #include <set>
  12. #include <queue>
  13. #include <stack>
  14. #include <vector>
  15. #include <algorithm>
  16.  
  17. using namespace std;
  18.  
  19. #define pb push_back
  20. #define fast_cin() ios_base::sync_with_stdio(false); cin.tie(NULL)
  21.  
  22. typedef long long ll;
  23. typedef long double ld;
  24. typedef pair <int, int> pii;
  25. typedef pair <ll, ll> pll;
  26.  
  27.  
  28. // 2-SAT solver based on Kosaraju's algorithm.
  29. // Variables are 0-based. Positive variables are stored in vertices 2n, corresponding negative variables in 2n+1
  30. // TODO: This is quite slow (3x-4x slower than Gabow's algorithm)
  31. struct TwoSat {
  32. int n;
  33. vector<vector<int> > adj, radj, scc;
  34. vector<int> sid, vis, val;
  35. stack<int> stk;
  36. int scnt;
  37.  
  38. // n: number of variables, including negations
  39. TwoSat(int n): n(n), adj(n), radj(n), sid(n), vis(n), val(n, -1) {}
  40.  
  41. // adds an implication
  42. void impl(int x, int y) { adj[x].push_back(y); radj[y].push_back(x); }
  43. // adds a disjunction
  44. void vee(int x, int y) { impl(x^1, y); impl(y^1, x); }
  45. // forces variables to be equal
  46. void eq(int x, int y) { impl(x, y); impl(y, x); impl(x^1, y^1); impl(y^1, x^1); }
  47. // forces variable to be true
  48. void tru(int x) { impl(x^1, x); }
  49.  
  50. void dfs1(int x) {
  51. if (vis[x]++) return;
  52. for (int i = 0; i < adj[x].size(); i++) {
  53. dfs1(adj[x][i]);
  54. }
  55. stk.push(x);
  56. }
  57.  
  58. void dfs2(int x) {
  59. if (!vis[x]) return; vis[x] = 0;
  60. sid[x] = scnt; scc.back().push_back(x);
  61. for (int i = 0; i < radj[x].size(); i++) {
  62. dfs2(radj[x][i]);
  63. }
  64. }
  65.  
  66. // returns true if satisfiable, false otherwise
  67. // on completion, val[x] is the assigned value of variable x
  68. // note, val[x] = 0 implies val[x^1] = 1
  69. bool two_sat() {
  70. scnt = 0;
  71. for (int i = 0; i < n; i++) {
  72. dfs1(i);
  73. }
  74. while (!stk.empty()) {
  75. int v = stk.top(); stk.pop();
  76. if (vis[v]) {
  77. scc.push_back(vector<int>());
  78. dfs2(v);
  79. scnt++;
  80. }
  81. }
  82. for (int i = 0; i < n; i += 2) {
  83. if (sid[i] == sid[i+1]) return false;
  84. }
  85. vector<int> must(scnt);
  86. for (int i = 0; i < scnt; i++) {
  87. for (int j = 0; j < scc[i].size(); j++) {
  88. val[scc[i][j]] = must[i];
  89. must[sid[scc[i][j]^1]] = !must[i];
  90. }
  91. }
  92. return true;
  93. }
  94. };
  95.  
  96. int main() {
  97. fast_cin();
  98. TwoSat TS(6);
  99. TS.impl(0, 4);
  100. TS.impl(2, 5);
  101. cout << TS.two_sat() << endl;
  102. for (int i = 0; i < 6; ++i) {
  103. cout << i << ' ' << TS.val[i] << endl;
  104. }
  105. }
Success #stdin #stdout 0s 4580KB
stdin
Standard input is empty
stdout
1
0 1
1 0
2 1
3 0
4 1
5 0