2-SAT + 二分
作为第二道2-SAT没什么好说的很简单,相对LA3211已经显示出基本模型了
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2000;
struct TwoSAT {
int n;
vector<int> G[MAXN * 2 + 10];
bool mark[MAXN * 2 + 10];
int S[MAXN * 2 + 10], c;
bool dfs(int u) {
if(mark[u ^ 1]) return 0;
if(mark[u]) return 1;
mark[u] = 1;
S[c++] = u;
for(int i = 0; i < G[u].size(); i++)
if(!dfs(G[u][i])) return 0;
return 1;
}
void init(int n) {
this->n = n;
for(int i = 0; i < n * 2; i++) G[i].clear();
memset(mark, 0, sizeof(mark));
}
void add_clause(int x, int xval, int y, int yval) {
x = x * 2 + xval;
y = y * 2 + yval;
G[x ^ 1].push_back(y);
G[y ^ 1].push_back(x);
}
bool solve() {
for(int i = 0; i < n * 2; i += 2) {
c = 0;
if(!dfs(i)) {
while(c != 0) mark[S[--c]] = 0;
if(!dfs(i ^ 1)) return 0;
}
}
return 1;
}
} sp;
int n, T[MAXN + 10][2];
bool check(int diff) {
sp.init(n);
for(int i = 0; i < n; i++) for(int a = 0; a < 2; a++)
for(int j = i + 1; j < n; j++) for(int b = 0; b < 2; b++)
if(abs(T[i][a] - T[j][b]) < diff) sp.add_clause(i, a ^ 1, j, b ^ 1);
return sp.solve();
}
int main() {
while(scanf("%d", &n) == 1 && n) {
int L = 0, R = 0;
for(int i = 0; i < n; i++) for(int a = 0; a < 2; a++) {
scanf("%d", &T[i][a]);
R = max(R, T[i][a]);
}
while(L < R) {
int M = L + (R - L + 1) / 2;
if(check(M)) L = M;
else R = M - 1;
}
printf("%d\n", L);
}
return 0;
}