UVALive - 3211 - Now or later(图论——2-SAT)
Posted npugen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVALive - 3211 - Now or later(图论——2-SAT)相关的知识,希望对你有一定的参考价值。
Problem UVALive - 3211 - Now or later
Time Limit: 9000 mSec
Problem Description
Input
Output
Sample Input
10 44 156 153 182 48 109 160 201 55 186 54 207 55 165 17 58 132 160 87 197
Sample Output
10
题解:2-SAT问题板子题,这个问题主要是理论难度比较大,有了结论之后代码很容易,有专门的论文阐释算法的正确性,看了几位大佬写的,基本上明白是怎么一回事,理解不深刻,就不在这里胡扯了,直接上代码。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define REP(i, n) for (int i = 1; i <= (n); i++) 6 #define sqr(x) ((x) * (x)) 7 8 const int maxn = 2000 + 10; 9 const int maxm = 30 + 10; 10 const int maxs = 10000 + 10; 11 12 typedef long long LL; 13 typedef pair<int, int> pii; 14 typedef pair<double, double> pdd; 15 16 const LL unit = 1LL; 17 const int INF = 0x3f3f3f3f; 18 const LL mod = 1000000007; 19 const double eps = 1e-14; 20 const double inf = 1e15; 21 const double pi = acos(-1.0); 22 23 struct TwoSAT 24 { 25 int n; 26 vector<int> G[maxn * 2]; 27 bool mark[maxn * 2]; 28 int S[maxn * 2], c; 29 30 bool dfs(int x) 31 { 32 if (mark[x ^ 1]) 33 return false; 34 if (mark[x]) 35 return true; 36 mark[x] = true; 37 S[c++] = x; 38 for (auto v : G[x]) 39 { 40 if (!dfs(v)) 41 return false; 42 } 43 return true; 44 } 45 46 void init(int n) 47 { 48 this->n = n; 49 for (int i = 0; i < n * 2; i++) 50 { 51 G[i].clear(); 52 } 53 memset(mark, 0, sizeof(mark)); 54 } 55 56 void add_clause(int x, int xval, int y, int yval) 57 { 58 x = x * 2 + xval; 59 y = y * 2 + yval; 60 G[x ^ 1].push_back(y); 61 G[y ^ 1].push_back(x); 62 } 63 64 bool solve() 65 { 66 for (int i = 0; i < n * 2; i += 2) 67 { 68 if (!mark[i] && !mark[i + 1]) 69 { 70 c = 0; 71 if (!dfs(i)) 72 { 73 while (c > 0) 74 { 75 mark[S[--c]] = false; 76 } 77 if (!dfs(i + 1)) 78 return false; 79 } 80 } 81 } 82 return true; 83 } 84 }; 85 86 TwoSAT solver; 87 88 int n, T[maxn][2]; 89 90 bool Judge(int lim) 91 { 92 solver.init(n); 93 for (int i = 0; i < n; i++) 94 { 95 for (int a = 0; a < 2; a++) 96 { 97 for (int j = i + 1; j < n; j++) 98 { 99 for (int b = 0; b < 2; b++) 100 { 101 if (abs(T[i][a] - T[j][b]) < lim) 102 { 103 solver.add_clause(i, a ^ 1, j, b ^ 1); 104 } 105 } 106 } 107 } 108 } 109 return solver.solve(); 110 } 111 112 main() 113 { 114 ios::sync_with_stdio(false); 115 cin.tie(0); 116 //freopen("input.txt", "r", stdin); 117 //freopen("output.txt", "w", stdout); 118 while (cin >> n && n) 119 { 120 int le = 0, ri = 0; 121 for (int i = 0; i < n; i++) 122 { 123 for (int j = 0; j < 2; j++) 124 { 125 cin >> T[i][j]; 126 ri = max(ri, T[i][j]); 127 } 128 } 129 130 int ans = 0; 131 while (le <= ri) 132 { 133 int mid = (le + ri) >> 1; 134 if (Judge(mid)) 135 { 136 ans = mid; 137 le = mid + 1; 138 } 139 else 140 { 141 ri = mid - 1; 142 } 143 } 144 cout << ans << endl; 145 } 146 return 0; 147 }
以上是关于UVALive - 3211 - Now or later(图论——2-SAT)的主要内容,如果未能解决你的问题,请参考以下文章