#include<bits/stdc++.h>
#define debu
using namespace std;
const int maxn=2*1e3+50;
struct TwoSAT
{
int n;
vector<int> G[maxn*2];
bool mark[maxn*2];
int S[maxn*2],c;
bool dfs(int x)
{
if(mark[x^1]) return false;
if(mark[x]) return true;
mark[x]=true;
S[c++]=x;
for(int i=0; i<G[x].size(); i++)
if(!dfs(G[x][i])) return false;
return true;
}
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)
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;
}
};
int n,maxt;
TwoSAT ans;
int g[maxn][2];
int check(int val)
{
ans.init(n);
for(int i=0; i<n; i++)
for(int j=i+1; j<n; j++)
{
if(abs(g[i][0]-g[j][0])<val) ans.add_clause(i,0,j,0);
if(abs(g[i][0]-g[j][1])<val) ans.add_clause(i,0,j,1);
if(abs(g[i][1]-g[j][0])<val) ans.add_clause(i,1,j,0);
if(abs(g[i][1]-g[j][1])<val) ans.add_clause(i,1,j,1);
}
return ans.solve();
}
int solve()
{
int l=0,r=maxt,mid;
while(l<=r)
{
mid=(l+r)>>1;
// cout<<l<<" "<<r<<endl;
if(check(mid)) l=mid+1;
else r=mid-1;
}
return r;
}
int main()
{
#ifdef debug
freopen("in.in","r",stdin);
#endif // debug
while(scanf("%d",&n)!=EOF)
{
maxt=0;
memset(g,0,sizeof(g));
for(int i=0; i<n; i++)
{
for(int j=0; j<2; j++)
{
scanf("%d",&g[i][j]);
maxt=max(maxt,g[i][j]);
}
}
printf("%d\n",solve());
}
return 0;
}
题目地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1212
题解:二分时间间隔val,对于每对不满足条件(例如abs(early[i]-later[j])<val,x[i]==1表示i选择早到,x[i]==0表示i选择晚到,则x[i]==1与x[j]==0不能同时选择(即2-SAT中的限制条件)),所以若2-SAT有解,则说明当前val可行,二分求最大值即可。