题意及题解参见lrj训练指南
#include<bits/stdc++.h> using namespace std; const int maxn=4e3+5; struct TwoSAT { int n; vector<int> adj[maxn*2]; bool mark[maxn*2]; int S[maxn*2],c; void init(int n) { this->n=n; for(int i=0;i<n*2;i++) adj[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; adj[x^1].push_back(y); adj[y^1].push_back(x); } bool dfs(int x) { if(mark[x^1]) return false; if(mark[x]) return true; mark[x]=true; S[c++]=x; for(int v:adj[x]) if(!dfs(v)) return false; return true; } bool ok() { for(int i=0;i<n*2;i+=2) if(!mark[i]&&!mark[i+1]) { c=0; if(!dfs(i)) { while(c>0) mark[S[--c]]=false; if(!dfs(i+1)) return false; } } return true; } }; //============================================================= TwoSAT solver; int n,T[maxn][2]; bool test(int diff) { solver.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) solver.add_clause(i,a^1,j,b^1); return solver.ok(); } int main() { while(scanf("%d",&n)>0&&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(R-L>1) { int M=(L+R)/2; if(test(M)) L=M; else R=M; } printf("%d ",L); } }